playback: eliminate old viewpager stuff
This commit is contained in:
parent
b0dd13b9a3
commit
4cb309f01f
7 changed files with 77 additions and 63 deletions
|
|
@ -29,27 +29,20 @@ import androidx.activity.result.contract.ActivityResultContracts
|
||||||
import androidx.appcompat.widget.Toolbar
|
import androidx.appcompat.widget.Toolbar
|
||||||
import androidx.core.view.updatePadding
|
import androidx.core.view.updatePadding
|
||||||
import androidx.fragment.app.activityViewModels
|
import androidx.fragment.app.activityViewModels
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
|
||||||
import androidx.viewpager2.widget.ViewPager2
|
|
||||||
import androidx.viewpager2.widget.ViewPager2.OnPageChangeCallback
|
|
||||||
import dagger.hilt.android.AndroidEntryPoint
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
import java.lang.reflect.Field
|
|
||||||
import kotlin.math.abs
|
|
||||||
import org.oxycblt.auxio.R
|
import org.oxycblt.auxio.R
|
||||||
import org.oxycblt.auxio.databinding.FragmentPlaybackPanelBinding
|
import org.oxycblt.auxio.databinding.FragmentPlaybackPanelBinding
|
||||||
import org.oxycblt.auxio.detail.DetailViewModel
|
import org.oxycblt.auxio.detail.DetailViewModel
|
||||||
import org.oxycblt.auxio.list.ListViewModel
|
import org.oxycblt.auxio.list.ListViewModel
|
||||||
import org.oxycblt.auxio.list.adapter.UpdateInstructions
|
|
||||||
import org.oxycblt.auxio.music.MusicParent
|
import org.oxycblt.auxio.music.MusicParent
|
||||||
import org.oxycblt.auxio.music.Song
|
import org.oxycblt.auxio.music.Song
|
||||||
import org.oxycblt.auxio.playback.queue.QueueViewModel
|
import org.oxycblt.auxio.music.resolveNames
|
||||||
import org.oxycblt.auxio.playback.state.RepeatMode
|
import org.oxycblt.auxio.playback.state.RepeatMode
|
||||||
import org.oxycblt.auxio.playback.ui.PlaybackPagerAdapter
|
import org.oxycblt.auxio.playback.ui.PlaybackPagerAdapter
|
||||||
import org.oxycblt.auxio.playback.ui.StyledSeekBar
|
import org.oxycblt.auxio.playback.ui.StyledSeekBar
|
||||||
import org.oxycblt.auxio.playback.ui.SwipeCoverView
|
import org.oxycblt.auxio.playback.ui.SwipeCoverView
|
||||||
import org.oxycblt.auxio.ui.ViewBindingFragment
|
import org.oxycblt.auxio.ui.ViewBindingFragment
|
||||||
import org.oxycblt.auxio.util.collectImmediately
|
import org.oxycblt.auxio.util.collectImmediately
|
||||||
import org.oxycblt.auxio.util.lazyReflectedField
|
|
||||||
import org.oxycblt.auxio.util.logD
|
import org.oxycblt.auxio.util.logD
|
||||||
import org.oxycblt.auxio.util.overrideOnOverflowMenuClick
|
import org.oxycblt.auxio.util.overrideOnOverflowMenuClick
|
||||||
import org.oxycblt.auxio.util.showToast
|
import org.oxycblt.auxio.util.showToast
|
||||||
|
|
@ -71,7 +64,6 @@ class PlaybackPanelFragment :
|
||||||
SwipeCoverView.OnSwipeListener {
|
SwipeCoverView.OnSwipeListener {
|
||||||
private val playbackModel: PlaybackViewModel by activityViewModels()
|
private val playbackModel: PlaybackViewModel by activityViewModels()
|
||||||
private val detailModel: DetailViewModel by activityViewModels()
|
private val detailModel: DetailViewModel by activityViewModels()
|
||||||
private val queueModel: QueueViewModel by activityViewModels()
|
|
||||||
private val listModel: ListViewModel by activityViewModels()
|
private val listModel: ListViewModel by activityViewModels()
|
||||||
private var equalizerLauncher: ActivityResultLauncher<Intent>? = null
|
private var equalizerLauncher: ActivityResultLauncher<Intent>? = null
|
||||||
private var coverAdapter: PlaybackPagerAdapter? = null
|
private var coverAdapter: PlaybackPagerAdapter? = null
|
||||||
|
|
@ -111,15 +103,11 @@ class PlaybackPanelFragment :
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// cover carousel adapter
|
|
||||||
coverAdapter = PlaybackPagerAdapter(this)
|
|
||||||
binding.playbackCoverPager.apply {
|
|
||||||
adapter = coverAdapter
|
|
||||||
registerOnPageChangeCallback(OnCoverChangedCallback(queueModel))
|
|
||||||
val recycler = VP_RECYCLER_FIELD.get(this@apply) as RecyclerView
|
|
||||||
recycler.isNestedScrollingEnabled = false
|
|
||||||
}
|
|
||||||
binding.playbackCover.onSwipeListener = this
|
binding.playbackCover.onSwipeListener = this
|
||||||
|
binding.playbackSong.setOnClickListener { navigateToCurrentSong() }
|
||||||
|
binding.playbackArtist.setOnClickListener { navigateToCurrentArtist() }
|
||||||
|
binding.playbackAlbum.setOnClickListener { navigateToCurrentAlbum() }
|
||||||
|
|
||||||
binding.playbackSeekBar.listener = this
|
binding.playbackSeekBar.listener = this
|
||||||
|
|
||||||
// Set up actions
|
// Set up actions
|
||||||
|
|
@ -137,8 +125,6 @@ class PlaybackPanelFragment :
|
||||||
collectImmediately(playbackModel.repeatMode, ::updateRepeat)
|
collectImmediately(playbackModel.repeatMode, ::updateRepeat)
|
||||||
collectImmediately(playbackModel.isPlaying, ::updatePlaying)
|
collectImmediately(playbackModel.isPlaying, ::updatePlaying)
|
||||||
collectImmediately(playbackModel.isShuffled, ::updateShuffled)
|
collectImmediately(playbackModel.isShuffled, ::updateShuffled)
|
||||||
collectImmediately(queueModel.queue, ::updateQueue)
|
|
||||||
collectImmediately(queueModel.index, ::updateQueuePosition)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDestroyBinding(binding: FragmentPlaybackPanelBinding) {
|
override fun onDestroyBinding(binding: FragmentPlaybackPanelBinding) {
|
||||||
|
|
@ -190,7 +176,12 @@ class PlaybackPanelFragment :
|
||||||
}
|
}
|
||||||
|
|
||||||
val binding = requireBinding()
|
val binding = requireBinding()
|
||||||
|
val context = requireContext()
|
||||||
logD("Updating song display: $song")
|
logD("Updating song display: $song")
|
||||||
|
binding.playbackCover.bind(song)
|
||||||
|
binding.playbackSong.text = song.name.resolve(context)
|
||||||
|
binding.playbackArtist.text = song.artists.resolveNames(context)
|
||||||
|
binding.playbackAlbum.text = song.album.name.resolve(context)
|
||||||
binding.playbackSeekBar.durationDs = song.durationMs.msToDs()
|
binding.playbackSeekBar.durationDs = song.durationMs.msToDs()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -220,43 +211,15 @@ class PlaybackPanelFragment :
|
||||||
requireBinding().playbackShuffle.isActivated = isShuffled
|
requireBinding().playbackShuffle.isActivated = isShuffled
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun navigateToCurrentSong() {
|
private fun navigateToCurrentSong() {
|
||||||
playbackModel.song.value?.let(detailModel::showAlbum)
|
playbackModel.song.value?.let(detailModel::showAlbum)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun navigateToCurrentArtist() {
|
private fun navigateToCurrentArtist() {
|
||||||
playbackModel.song.value?.let(detailModel::showArtist)
|
playbackModel.song.value?.let(detailModel::showArtist)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun navigateToCurrentAlbum() {
|
private fun navigateToCurrentAlbum() {
|
||||||
playbackModel.song.value?.let { detailModel.showAlbum(it.album) }
|
playbackModel.song.value?.let { detailModel.showAlbum(it.album) }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun navigateToMenu() {
|
|
||||||
// TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
private class OnCoverChangedCallback(private val queueViewModel: QueueViewModel) :
|
|
||||||
OnPageChangeCallback() {
|
|
||||||
|
|
||||||
private var targetPosition = RecyclerView.NO_POSITION
|
|
||||||
|
|
||||||
override fun onPageSelected(position: Int) {
|
|
||||||
super.onPageSelected(position)
|
|
||||||
targetPosition = position
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onPageScrollStateChanged(state: Int) {
|
|
||||||
super.onPageScrollStateChanged(state)
|
|
||||||
if (state == ViewPager2.SCROLL_STATE_IDLE &&
|
|
||||||
targetPosition != RecyclerView.NO_POSITION &&
|
|
||||||
targetPosition != queueViewModel.index.value) {
|
|
||||||
queueViewModel.goto(targetPosition)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private companion object {
|
|
||||||
val VP_RECYCLER_FIELD: Field by lazyReflectedField(ViewPager2::class, "mRecyclerView")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@ import android.os.Bundle
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import androidx.core.view.isInvisible
|
import androidx.core.view.isInvisible
|
||||||
import androidx.fragment.app.activityViewModels
|
import androidx.fragment.app.activityViewModels
|
||||||
|
import androidx.fragment.app.viewModels
|
||||||
import androidx.recyclerview.widget.ItemTouchHelper
|
import androidx.recyclerview.widget.ItemTouchHelper
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
|
@ -42,7 +43,7 @@ import org.oxycblt.auxio.util.logD
|
||||||
*/
|
*/
|
||||||
@AndroidEntryPoint
|
@AndroidEntryPoint
|
||||||
class QueueFragment : ViewBindingFragment<FragmentQueueBinding>(), EditClickListListener<Song> {
|
class QueueFragment : ViewBindingFragment<FragmentQueueBinding>(), EditClickListListener<Song> {
|
||||||
private val queueModel: QueueViewModel by activityViewModels()
|
private val queueModel: QueueViewModel by viewModels()
|
||||||
private val playbackModel: PlaybackViewModel by activityViewModels()
|
private val playbackModel: PlaybackViewModel by activityViewModels()
|
||||||
private val queueAdapter = QueueAdapter(this)
|
private val queueAdapter = QueueAdapter(this)
|
||||||
private var touchHelper: ItemTouchHelper? = null
|
private var touchHelper: ItemTouchHelper? = null
|
||||||
|
|
|
||||||
|
|
@ -73,10 +73,7 @@ class CoverViewHolder private constructor(private val binding: ItemPlaybackSongB
|
||||||
val context = binding.root.context
|
val context = binding.root.context
|
||||||
binding.playbackCover.bind(item)
|
binding.playbackCover.bind(item)
|
||||||
// binding.playbackCover.bind(item)
|
// binding.playbackCover.bind(item)
|
||||||
binding.playbackSong.apply {
|
binding.playbackSong.apply { text = item.name.resolve(context) }
|
||||||
text = item.name.resolve(context)
|
|
||||||
setOnClickListener { listener.navigateToCurrentSong() }
|
|
||||||
}
|
|
||||||
binding.playbackArtist.apply {
|
binding.playbackArtist.apply {
|
||||||
text = item.artists.resolveNames(context)
|
text = item.artists.resolveNames(context)
|
||||||
setOnClickListener { listener.navigateToCurrentArtist() }
|
setOnClickListener { listener.navigateToCurrentArtist() }
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.oxycblt.auxio.playback.ui
|
package org.oxycblt.auxio.playback.ui
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
|
|
@ -77,8 +77,7 @@ constructor(context: Context, attrs: AttributeSet? = null, @AttrRes defStyleAttr
|
||||||
val diffX = e2.x - e1.x
|
val diffX = e2.x - e1.x
|
||||||
if (abs(diffX) > abs(diffY) &&
|
if (abs(diffX) > abs(diffY) &&
|
||||||
abs(diffX) > viewConfig.scaledTouchSlop &&
|
abs(diffX) > viewConfig.scaledTouchSlop &&
|
||||||
abs(velocityX) > viewConfig.scaledMinimumFlingVelocity
|
abs(velocityX) > viewConfig.scaledMinimumFlingVelocity) {
|
||||||
) {
|
|
||||||
if (diffX > 0) {
|
if (diffX > 0) {
|
||||||
onSwipeRight()
|
onSwipeRight()
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -102,6 +101,7 @@ constructor(context: Context, attrs: AttributeSet? = null, @AttrRes defStyleAttr
|
||||||
interface OnSwipeListener {
|
interface OnSwipeListener {
|
||||||
|
|
||||||
fun onSwipePrevious()
|
fun onSwipePrevious()
|
||||||
|
|
||||||
fun onSwipeNext()
|
fun onSwipeNext()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -62,7 +62,8 @@
|
||||||
app:layout_constraintBottom_toTopOf="@+id/playback_seek_bar"
|
app:layout_constraintBottom_toTopOf="@+id/playback_seek_bar"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/playback_toolbar" />
|
tools:text="Album Name" />
|
||||||
|
|
||||||
|
|
||||||
<org.oxycblt.auxio.playback.ui.StyledSeekBar
|
<org.oxycblt.auxio.playback.ui.StyledSeekBar
|
||||||
android:id="@+id/playback_seek_bar"
|
android:id="@+id/playback_seek_bar"
|
||||||
|
|
@ -153,4 +154,4 @@
|
||||||
|
|
||||||
</org.oxycblt.auxio.playback.ui.ForcedLTRFrameLayout>
|
</org.oxycblt.auxio.playback.ui.ForcedLTRFrameLayout>
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
@ -44,11 +44,25 @@
|
||||||
android:id="@+id/playback_artist"
|
android:id="@+id/playback_artist"
|
||||||
style="@style/Widget.Auxio.TextView.Secondary.Marquee"
|
style="@style/Widget.Auxio.TextView.Secondary.Marquee"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="0dp"
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="@dimen/spacing_medium"
|
||||||
|
android:layout_marginEnd="@dimen/spacing_medium"
|
||||||
|
app:layout_constraintBottom_toTopOf="@+id/playback_album"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
tools:text="Artist Name" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/playback_album"
|
||||||
|
style="@style/Widget.Auxio.TextView.Secondary.Marquee"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="@dimen/spacing_medium"
|
||||||
|
android:layout_marginEnd="@dimen/spacing_medium"
|
||||||
app:layout_constraintBottom_toTopOf="@+id/playback_seek_bar"
|
app:layout_constraintBottom_toTopOf="@+id/playback_seek_bar"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/playback_toolbar" />
|
tools:text="Album Name" />
|
||||||
|
|
||||||
<org.oxycblt.auxio.playback.ui.StyledSeekBar
|
<org.oxycblt.auxio.playback.ui.StyledSeekBar
|
||||||
android:id="@+id/playback_seek_bar"
|
android:id="@+id/playback_seek_bar"
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@
|
||||||
app:title="@string/lbl_playback"
|
app:title="@string/lbl_playback"
|
||||||
tools:subtitle="@string/lbl_all_songs" />
|
tools:subtitle="@string/lbl_all_songs" />
|
||||||
|
|
||||||
|
|
||||||
<org.oxycblt.auxio.playback.ui.SwipeCoverView
|
<org.oxycblt.auxio.playback.ui.SwipeCoverView
|
||||||
android:id="@+id/playback_cover"
|
android:id="@+id/playback_cover"
|
||||||
style="@style/Widget.Auxio.Image.Full"
|
style="@style/Widget.Auxio.Image.Full"
|
||||||
|
|
@ -24,11 +25,48 @@
|
||||||
app:enablePlaybackIndicator="false"
|
app:enablePlaybackIndicator="false"
|
||||||
app:enableSelectionBadge="false"
|
app:enableSelectionBadge="false"
|
||||||
app:layout_constraintBottom_toTopOf="@+id/playback_seek_bar"
|
app:layout_constraintBottom_toTopOf="@+id/playback_seek_bar"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/playback_toolbar"
|
app:layout_constraintTop_toBottomOf="@+id/playback_toolbar"
|
||||||
app:layout_constraintVertical_chainStyle="packed" />
|
app:layout_constraintVertical_chainStyle="packed" />
|
||||||
|
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/playback_info_container"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="@dimen/spacing_medium"
|
||||||
|
android:layout_marginEnd="@dimen/spacing_medium"
|
||||||
|
android:orientation="vertical"
|
||||||
|
app:layout_constraintBottom_toTopOf="@+id/playback_seek_bar"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintHorizontal_bias="0.5"
|
||||||
|
app:layout_constraintStart_toEndOf="@+id/playback_cover"
|
||||||
|
app:layout_constraintTop_toTopOf="@+id/playback_cover"
|
||||||
|
app:layout_constraintVertical_chainStyle="packed">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/playback_song"
|
||||||
|
style="@style/Widget.Auxio.TextView.Primary"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
tools:text="Song Name" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/playback_artist"
|
||||||
|
style="@style/Widget.Auxio.TextView.Secondary.Marquee"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
tools:text="Artist Name" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/playback_album"
|
||||||
|
style="@style/Widget.Auxio.TextView.Secondary.Marquee"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
tools:text="Album Name" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
<org.oxycblt.auxio.playback.ui.StyledSeekBar
|
<org.oxycblt.auxio.playback.ui.StyledSeekBar
|
||||||
android:id="@+id/playback_seek_bar"
|
android:id="@+id/playback_seek_bar"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue