From b9306208692a0016f4e1d04b7d1fdce57c930f6c Mon Sep 17 00:00:00 2001 From: brahmkshatriya <69040506+brahmkshatriya@users.noreply.github.com> Date: Thu, 8 Feb 2024 22:46:55 +0530 Subject: [PATCH] - Next/Previous button work now - Refactor PlayerListener a bit - Create TrackWithStream - Refactor Loading with the Paging Adapter --- .../echo/data/models/Playlist.kt | 6 +- .../echo/ui/adapters/ClickListener.kt | 6 ++ .../echo/ui/adapters/MediaItemAdapter.kt | 8 +- .../ui/adapters/MediaItemsContainerAdapter.kt | 26 ++++- .../echo/ui/home/HomeFragment.kt | 28 +++-- .../echo/ui/home/HomeViewModel.kt | 8 +- .../brahmkshatriya/echo/ui/player/Player.kt | 47 ++++---- .../echo/ui/player/PlayerListener.kt | 100 +++++++++++------- .../echo/ui/player/PlayerViewModel.kt | 33 ++++-- .../echo/ui/player/TrackWithStream.kt | 33 ++++++ .../echo/ui/search/SearchFragment.kt | 14 ++- app/src/main/res/color/button_play_pause.xml | 4 +- app/src/main/res/color/button_player.xml | 5 + app/src/main/res/layout/bottom_player.xml | 22 ++-- .../res/layout/skeleton_item_container.xml | 2 +- 15 files changed, 235 insertions(+), 107 deletions(-) create mode 100644 app/src/main/java/dev/brahmkshatriya/echo/ui/adapters/ClickListener.kt create mode 100644 app/src/main/java/dev/brahmkshatriya/echo/ui/player/TrackWithStream.kt create mode 100644 app/src/main/res/color/button_player.xml diff --git a/app/src/main/java/dev/brahmkshatriya/echo/data/models/Playlist.kt b/app/src/main/java/dev/brahmkshatriya/echo/data/models/Playlist.kt index 09ef1bad..436a8cfb 100644 --- a/app/src/main/java/dev/brahmkshatriya/echo/data/models/Playlist.kt +++ b/app/src/main/java/dev/brahmkshatriya/echo/data/models/Playlist.kt @@ -1,10 +1,8 @@ package dev.brahmkshatriya.echo.data.models import android.net.Uri -import androidx.paging.PagingData -import kotlinx.coroutines.flow.Flow -sealed class Playlist{ +sealed class Playlist { open class Small( open val uri: Uri, @@ -22,7 +20,7 @@ sealed class Playlist{ override val title: String, override val cover: ImageHolder?, val author: User?, - val tracks: Flow>, + val tracks: List, val creationDate: String?, val duration: Long?, val description: String?, diff --git a/app/src/main/java/dev/brahmkshatriya/echo/ui/adapters/ClickListener.kt b/app/src/main/java/dev/brahmkshatriya/echo/ui/adapters/ClickListener.kt new file mode 100644 index 00000000..cb20fbeb --- /dev/null +++ b/app/src/main/java/dev/brahmkshatriya/echo/ui/adapters/ClickListener.kt @@ -0,0 +1,6 @@ +package dev.brahmkshatriya.echo.ui.adapters + +interface ClickListener { + fun onClick(item: T) + fun onLongClick(item: T) +} \ No newline at end of file diff --git a/app/src/main/java/dev/brahmkshatriya/echo/ui/adapters/MediaItemAdapter.kt b/app/src/main/java/dev/brahmkshatriya/echo/ui/adapters/MediaItemAdapter.kt index 47b54cc1..d37e5277 100644 --- a/app/src/main/java/dev/brahmkshatriya/echo/ui/adapters/MediaItemAdapter.kt +++ b/app/src/main/java/dev/brahmkshatriya/echo/ui/adapters/MediaItemAdapter.kt @@ -13,7 +13,7 @@ import dev.brahmkshatriya.echo.databinding.ItemMediaBinding import dev.brahmkshatriya.echo.ui.utils.loadInto class MediaItemAdapter( - private val play : (Track) -> Unit + private val listener: ClickListener ) : PagingDataAdapter( MediaItemComparator @@ -31,7 +31,11 @@ class MediaItemAdapter( binding.title.text = item.track.title item.track.cover?.loadInto(binding.imageView) binding.root.setOnClickListener { - play(item.track) + listener.onClick(item.track) + } + binding.root.setOnLongClickListener { + listener.onLongClick(item.track) + true } } diff --git a/app/src/main/java/dev/brahmkshatriya/echo/ui/adapters/MediaItemsContainerAdapter.kt b/app/src/main/java/dev/brahmkshatriya/echo/ui/adapters/MediaItemsContainerAdapter.kt index e9e874d2..27d1f6c8 100644 --- a/app/src/main/java/dev/brahmkshatriya/echo/ui/adapters/MediaItemsContainerAdapter.kt +++ b/app/src/main/java/dev/brahmkshatriya/echo/ui/adapters/MediaItemsContainerAdapter.kt @@ -4,7 +4,9 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import androidx.lifecycle.Lifecycle +import androidx.paging.LoadState import androidx.paging.PagingDataAdapter +import androidx.recyclerview.widget.ConcatAdapter import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager.HORIZONTAL @@ -18,10 +20,24 @@ import dev.brahmkshatriya.echo.ui.utils.loadInto class MediaItemsContainerAdapter( private val lifecycle: Lifecycle, - private val play: (Track) -> Unit, + private val listener: ClickListener, ) : PagingDataAdapter( MediaItemsContainerComparator ) { + + fun withLoadingFooter(): ConcatAdapter { + val footer = ContainerLoadingAdapter { + retry() + } + addLoadStateListener { loadStates -> + footer.loadState = when (loadStates.refresh) { + is LoadState.NotLoading -> loadStates.append + else -> loadStates.refresh + } + } + return ConcatAdapter(this, footer) + } + override fun getItemViewType(position: Int): Int { return getItem(position)?.let { when (it) { @@ -57,7 +73,7 @@ class MediaItemsContainerAdapter( binding.textView.text = category.title binding.recyclerView.layoutManager = LinearLayoutManager(binding.root.context, HORIZONTAL, false) - val adapter = MediaItemAdapter(play) + val adapter = MediaItemAdapter(listener) binding.recyclerView.adapter = adapter adapter.submitData(lifecycle, category.list) } @@ -65,7 +81,11 @@ class MediaItemsContainerAdapter( is MediaItemsContainerBinding.Track -> { val binding = holder.container.binding val track = (item as MediaItemsContainer.TrackItem).track - binding.root.setOnClickListener { play(track) } + binding.root.setOnClickListener { listener.onClick(track) } + binding.root.setOnLongClickListener { + listener.onLongClick(track) + true + } binding.title.text = track.title diff --git a/app/src/main/java/dev/brahmkshatriya/echo/ui/home/HomeFragment.kt b/app/src/main/java/dev/brahmkshatriya/echo/ui/home/HomeFragment.kt index 6d5a245d..5345730d 100644 --- a/app/src/main/java/dev/brahmkshatriya/echo/ui/home/HomeFragment.kt +++ b/app/src/main/java/dev/brahmkshatriya/echo/ui/home/HomeFragment.kt @@ -6,12 +6,14 @@ import android.view.View import android.view.ViewGroup import androidx.fragment.app.Fragment import androidx.fragment.app.activityViewModels +import androidx.paging.LoadState import androidx.recyclerview.widget.ConcatAdapter import androidx.recyclerview.widget.LinearLayoutManager import dagger.hilt.android.AndroidEntryPoint import dev.brahmkshatriya.echo.R +import dev.brahmkshatriya.echo.data.models.Track import dev.brahmkshatriya.echo.databinding.FragmentRecyclerBinding -import dev.brahmkshatriya.echo.ui.adapters.ContainerLoadingAdapter +import dev.brahmkshatriya.echo.ui.adapters.ClickListener import dev.brahmkshatriya.echo.ui.adapters.HeaderAdapter import dev.brahmkshatriya.echo.ui.adapters.MediaItemsContainerAdapter import dev.brahmkshatriya.echo.ui.player.PlayerBackButtonHelper @@ -42,25 +44,33 @@ class HomeFragment : Fragment() { val headerAdapter = HeaderAdapter(R.string.home) val mediaItemsContainerAdapter = - MediaItemsContainerAdapter(viewLifecycleOwner.lifecycle, playerViewModel::play) + MediaItemsContainerAdapter(viewLifecycleOwner.lifecycle, object : ClickListener { + override fun onClick(item: Track) { + playerViewModel.play(item) + } - mediaItemsContainerAdapter.withLoadStateFooter(ContainerLoadingAdapter { - homeViewModel.loadFeed(homeViewModel.genre) - }) + override fun onLongClick(item: Track) { + playerViewModel.addToQueue(item) + } + }) - binding.recyclerView.adapter = ConcatAdapter(headerAdapter, mediaItemsContainerAdapter) + val concat = mediaItemsContainerAdapter.withLoadingFooter() + + binding.recyclerView.adapter = ConcatAdapter(headerAdapter, concat) binding.recyclerView.layoutManager = LinearLayoutManager(context) binding.swipeRefresh.setOnRefreshListener { - homeViewModel.loadFeed(homeViewModel.genre) + mediaItemsContainerAdapter.refresh() + } + + mediaItemsContainerAdapter.addLoadStateListener { + binding.swipeRefresh.isRefreshing = it.refresh is LoadState.Loading } homeViewModel.feed.observeFlow(viewLifecycleOwner) { - binding.swipeRefresh.isRefreshing = false if (it == null) return@observeFlow mediaItemsContainerAdapter.submitData(it) } - homeViewModel.loadFeed(homeViewModel.genre) } } \ No newline at end of file diff --git a/app/src/main/java/dev/brahmkshatriya/echo/ui/home/HomeViewModel.kt b/app/src/main/java/dev/brahmkshatriya/echo/ui/home/HomeViewModel.kt index 10acd80f..2a2745e3 100644 --- a/app/src/main/java/dev/brahmkshatriya/echo/ui/home/HomeViewModel.kt +++ b/app/src/main/java/dev/brahmkshatriya/echo/ui/home/HomeViewModel.kt @@ -19,12 +19,18 @@ class HomeViewModel @Inject constructor( private val homeClient: HomeFeedClient ) : ViewModel() { + init { + viewModelScope.launch { + loadFeed() + } + } + private val _feed: MutableStateFlow?> = MutableStateFlow(null) val feed = _feed.asStateFlow() val genre: String? = null - fun loadFeed(genre: String?) { + fun loadFeed() { viewModelScope.launch(Dispatchers.IO) { println("Loading Data") homeClient.getHomeFeed(genre).cachedIn(viewModelScope).collectLatest { diff --git a/app/src/main/java/dev/brahmkshatriya/echo/ui/player/Player.kt b/app/src/main/java/dev/brahmkshatriya/echo/ui/player/Player.kt index 0c45c5db..ed4a9f10 100644 --- a/app/src/main/java/dev/brahmkshatriya/echo/ui/player/Player.kt +++ b/app/src/main/java/dev/brahmkshatriya/echo/ui/player/Player.kt @@ -16,9 +16,7 @@ import com.google.android.material.checkbox.MaterialCheckBox.STATE_CHECKED import com.google.android.material.checkbox.MaterialCheckBox.STATE_UNCHECKED import dev.brahmkshatriya.echo.MainActivity import dev.brahmkshatriya.echo.R -import dev.brahmkshatriya.echo.data.models.StreamableAudio import dev.brahmkshatriya.echo.databinding.BottomPlayerBinding -import dev.brahmkshatriya.echo.ui.player.PlayerHelper.Companion.toMetaData import dev.brahmkshatriya.echo.ui.player.PlayerHelper.Companion.toTimeString import dev.brahmkshatriya.echo.ui.utils.dpToPx import dev.brahmkshatriya.echo.ui.utils.updatePaddingWithSystemInsets @@ -89,11 +87,11 @@ class Player( binding.collapsedTrackPlayPause.addOnCheckedStateChangedListener(playPauseListener) binding.trackNext.setOnClickListener { - player.seekToNextMediaItem() + player.seekToNext() } binding.trackPrevious.setOnClickListener { - player.seekToPreviousMediaItem() + player.seekToPrevious() } @@ -114,31 +112,26 @@ class Player( val listener = PlayerListener(player, binding, playPauseListener) player.addListener(listener) + fun addToQueue(it: TrackWithStream?): MediaItem? { + it ?: return null + val item = it.mediaItemBuilder() + listener.map[item.mediaMetadata] = it.track + player.addMediaItem(item) + player.prepare() + player.play() + return item + } + activity.lifecycleScope.launch { - viewModel.audioFlow.collectLatest { pair -> - pair?.run { - val track = this.first - val metadata = track.toMetaData() - listener.map(metadata, track) - - val builder = MediaItem.Builder() - .setMediaMetadata(metadata) - val item = when (val audio = this.second) { - is StreamableAudio.StreamableFile -> { - builder.setUri(audio.uri) - } - - is StreamableAudio.StreamableUrl -> { - builder.setUri(audio.url.url) - } - - is StreamableAudio.ByteStreamAudio -> TODO() - } - player.setMediaItem(item.build()) - player.prepare() - player.play() + launch { + viewModel.audioFlow.collectLatest { +// val item = addToQueue(it) ?: return@collectLatest + } + } + launch { + viewModel.audioQueueFlow.collectLatest { + addToQueue(it) } - } } } diff --git a/app/src/main/java/dev/brahmkshatriya/echo/ui/player/PlayerListener.kt b/app/src/main/java/dev/brahmkshatriya/echo/ui/player/PlayerListener.kt index 747db749..769e8ffa 100644 --- a/app/src/main/java/dev/brahmkshatriya/echo/ui/player/PlayerListener.kt +++ b/app/src/main/java/dev/brahmkshatriya/echo/ui/player/PlayerListener.kt @@ -1,11 +1,11 @@ package dev.brahmkshatriya.echo.ui.player import android.annotation.SuppressLint -import android.os.Handler -import android.os.Looper -import androidx.media3.common.C +import android.view.View import androidx.media3.common.MediaMetadata import androidx.media3.common.Player +import androidx.media3.common.Timeline +import androidx.media3.exoplayer.ExoPlayer import androidx.media3.session.MediaController import com.google.android.material.checkbox.MaterialCheckBox import dev.brahmkshatriya.echo.data.models.Track @@ -13,30 +13,24 @@ import dev.brahmkshatriya.echo.databinding.BottomPlayerBinding import dev.brahmkshatriya.echo.ui.player.PlayerHelper.Companion.toTimeString import dev.brahmkshatriya.echo.ui.utils.loadInto + class PlayerListener( private val player: MediaController, private val binding: BottomPlayerBinding, private val playPauseListener: MaterialCheckBox.OnCheckedStateChangedListener -) : - Player.Listener { +) : Player.Listener { + + private val updateProgressRunnable = Runnable { updateProgress() } + init { - //Poll each second to update the seekbar - val handler = Handler(Looper.getMainLooper()) - val runnable = object : Runnable { - override fun run() { - if(!binding.expandedSeekBar.isPressed) { - binding.collapsedSeekBar.progress = player.currentPosition.toInt() - binding.collapsedSeekBar.secondaryProgress = player.bufferedPosition.toInt() - - binding.expandedSeekBar.secondaryProgress = player.bufferedPosition.toInt() - binding.expandedSeekBar.progress = player.currentPosition.toInt() - - binding.trackCurrentTime.text = player.currentPosition.toTimeString() - } - handler.postDelayed(this, 1000) + val listener = this + binding.root.addOnAttachStateChangeListener(object : View.OnAttachStateChangeListener { + override fun onViewAttachedToWindow(p0: View) {} + override fun onViewDetachedFromWindow(p0: View) { + player.removeListener(listener) } - } - handler.post(runnable) + }) + binding.root.post(updateProgressRunnable) } @SuppressLint("SwitchIntDef") @@ -51,7 +45,7 @@ class PlayerListener( binding.trackPlayPause.isEnabled = true binding.collapsedTrackPlayPause.isEnabled = true - if (player.duration == C.TIME_UNSET) throw IllegalStateException("Duration is not set") +// if (player.duration == C.TIME_UNSET) throw IllegalStateException("Duration is not set") binding.collapsedSeekBar.isIndeterminate = false binding.expandedSeekBar.isEnabled = true @@ -62,6 +56,7 @@ class PlayerListener( binding.trackTotalTime.text = player.duration.toTimeString() } } + updateProgress() } override fun onIsPlayingChanged(isPlaying: Boolean) { @@ -73,17 +68,13 @@ class PlayerListener( binding.trackPlayPause.addOnCheckedStateChangedListener(playPauseListener) binding.collapsedTrackPlayPause.addOnCheckedStateChangedListener(playPauseListener) - } - - private val tracks = mutableMapOf() - fun map(metadata: MediaMetadata, track: Track) { - tracks[metadata] = track } + val map = mutableMapOf() override fun onMediaMetadataChanged(mediaMetadata: MediaMetadata) { + val track = map[mediaMetadata] ?: return - val track = tracks[mediaMetadata] ?: return binding.collapsedTrackTitle.text = track.title binding.expandedTrackTitle.text = track.title @@ -103,20 +94,53 @@ class PlayerListener( } override fun onPositionDiscontinuity( - oldPosition: Player.PositionInfo, - newPosition: Player.PositionInfo, - reason: Int + oldPosition: Player.PositionInfo, newPosition: Player.PositionInfo, reason: Int ) { - if (reason != Player.DISCONTINUITY_REASON_SEEK && reason != Player.DISCONTINUITY_REASON_SEEK_ADJUSTMENT) { - binding.collapsedSeekBar.progress = newPosition.positionMs.toInt() - binding.expandedSeekBar.progress = newPosition.positionMs.toInt() + updateNavigation() + updateProgress() + } + + override fun onTimelineChanged(timeline: Timeline, reason: Int) { + updateNavigation() + updateProgress() + } + + private fun updateProgress() { + if (!binding.root.isAttachedToWindow) return + + if (!binding.expandedSeekBar.isPressed) { + binding.collapsedSeekBar.progress = player.currentPosition.toInt() + binding.collapsedSeekBar.secondaryProgress = player.bufferedPosition.toInt() - binding.trackCurrentTime.text = newPosition.positionMs.toTimeString() + binding.expandedSeekBar.secondaryProgress = player.bufferedPosition.toInt() + binding.expandedSeekBar.progress = player.currentPosition.toInt() + + binding.trackCurrentTime.text = player.currentPosition.toTimeString() } + + binding.root.removeCallbacks(updateProgressRunnable) + val playbackState = player.playbackState + if (playbackState != ExoPlayer.STATE_IDLE && playbackState != ExoPlayer.STATE_ENDED) { + var delayMs: Long + if (player.playWhenReady && playbackState == ExoPlayer.STATE_READY) { + delayMs = 1000 - player.currentPosition % 1000 + if (delayMs < 200) { + delayMs += 1000 + } + } else { + delayMs = 1000 + } + binding.root.postDelayed(updateProgressRunnable, delayMs) + } + } - override fun onPlaylistMetadataChanged(mediaMetadata: MediaMetadata) { - super.onPlaylistMetadataChanged(mediaMetadata) - println(mediaMetadata) + private fun updateNavigation() { + if (!binding.root.isAttachedToWindow) return + val index = player.currentMediaItemIndex + val enablePrevious = index >= 0 + val enableNext = index < player.mediaItemCount - 1 + binding.trackNext.isEnabled = enableNext + binding.trackPrevious.isEnabled = enablePrevious } } diff --git a/app/src/main/java/dev/brahmkshatriya/echo/ui/player/PlayerViewModel.kt b/app/src/main/java/dev/brahmkshatriya/echo/ui/player/PlayerViewModel.kt index 1f4e79fb..332984a5 100644 --- a/app/src/main/java/dev/brahmkshatriya/echo/ui/player/PlayerViewModel.kt +++ b/app/src/main/java/dev/brahmkshatriya/echo/ui/player/PlayerViewModel.kt @@ -4,28 +4,47 @@ import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import dagger.hilt.android.lifecycle.HiltViewModel import dev.brahmkshatriya.echo.data.clients.TrackClient -import dev.brahmkshatriya.echo.data.models.StreamableAudio import dev.brahmkshatriya.echo.data.models.Track import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.delay import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.launch import javax.inject.Inject @HiltViewModel class PlayerViewModel @Inject constructor( - private val trackClient: TrackClient + private val trackClient: TrackClient, +// private val radioClient: RadioClient ) : ViewModel() { - val audioFlow = MutableStateFlow?>(null) + val audioFlow = MutableStateFlow(null) + val audioQueueFlow = MutableStateFlow(null) - private fun loadStreamable(track: Track) { + private suspend fun loadStreamable(track: Track) = + TrackWithStream(track, trackClient.getStreamable(track)) + + fun play(track: Track) { viewModelScope.launch(Dispatchers.IO) { - audioFlow.value = track to trackClient.getStreamable(track) + val stream = loadStreamable(track) + audioQueueFlow.value = stream + delay(10) + audioFlow.value = stream } } - fun play(track: Track) { - loadStreamable(track) + fun addToQueue(track: Track) { + viewModelScope.launch(Dispatchers.IO) { + audioQueueFlow.value = loadStreamable(track) + } } +// fun radio(track: Track){ +// viewModelScope.launch(Dispatchers.IO) { +// val playlist = radioClient.radio(track) +// playlist.tracks.forEach { +// audioQueueFlow.value = loadStreamable(it) +// } +// } +// } + } \ No newline at end of file diff --git a/app/src/main/java/dev/brahmkshatriya/echo/ui/player/TrackWithStream.kt b/app/src/main/java/dev/brahmkshatriya/echo/ui/player/TrackWithStream.kt new file mode 100644 index 00000000..0fee7677 --- /dev/null +++ b/app/src/main/java/dev/brahmkshatriya/echo/ui/player/TrackWithStream.kt @@ -0,0 +1,33 @@ +package dev.brahmkshatriya.echo.ui.player + +import androidx.media3.common.MediaItem +import dev.brahmkshatriya.echo.data.models.StreamableAudio +import dev.brahmkshatriya.echo.data.models.Track +import dev.brahmkshatriya.echo.ui.player.PlayerHelper.Companion.toMetaData + +class TrackWithStream( + val track: Track, + private val audio: StreamableAudio +) { + fun mediaItemBuilder(): MediaItem { + val builder = MediaItem.Builder() + + val item = when (audio) { + is StreamableAudio.StreamableFile -> { + builder.setUri(audio.uri) + } + + is StreamableAudio.StreamableUrl -> { + builder.setUri(audio.url.url) + } + + is StreamableAudio.ByteStreamAudio -> TODO() + } + + val metadata = track.toMetaData() + item.setMediaMetadata(metadata) + item.setTag(track) + + return item.build() + } +} \ No newline at end of file diff --git a/app/src/main/java/dev/brahmkshatriya/echo/ui/search/SearchFragment.kt b/app/src/main/java/dev/brahmkshatriya/echo/ui/search/SearchFragment.kt index a39e1259..a7847e35 100644 --- a/app/src/main/java/dev/brahmkshatriya/echo/ui/search/SearchFragment.kt +++ b/app/src/main/java/dev/brahmkshatriya/echo/ui/search/SearchFragment.kt @@ -9,7 +9,9 @@ import androidx.fragment.app.activityViewModels import androidx.recyclerview.widget.ConcatAdapter import androidx.recyclerview.widget.LinearLayoutManager import dagger.hilt.android.AndroidEntryPoint +import dev.brahmkshatriya.echo.data.models.Track import dev.brahmkshatriya.echo.databinding.FragmentSearchBinding +import dev.brahmkshatriya.echo.ui.adapters.ClickListener import dev.brahmkshatriya.echo.ui.adapters.MediaItemsContainerAdapter import dev.brahmkshatriya.echo.ui.adapters.SearchHeaderAdapter import dev.brahmkshatriya.echo.ui.player.PlayerBackButtonHelper @@ -51,9 +53,15 @@ class SearchFragment : Fragment() { } false } - val adapter = MediaItemsContainerAdapter(lifecycle){ - playerViewModel.play(it) - } + val adapter = MediaItemsContainerAdapter(lifecycle, object : ClickListener { + override fun onClick(item: Track) { + playerViewModel.play(item) + } + + override fun onLongClick(item: Track) { + playerViewModel.addToQueue(item) + } + }) binding.catRecyclerView.layoutManager = LinearLayoutManager(requireContext()) binding.catRecyclerView.adapter = ConcatAdapter(header, adapter) searchViewModel.result.observeFlow(viewLifecycleOwner) { diff --git a/app/src/main/res/color/button_play_pause.xml b/app/src/main/res/color/button_play_pause.xml index d17ff78d..82552ad7 100644 --- a/app/src/main/res/color/button_play_pause.xml +++ b/app/src/main/res/color/button_play_pause.xml @@ -1,5 +1,5 @@ - - + + \ No newline at end of file diff --git a/app/src/main/res/color/button_player.xml b/app/src/main/res/color/button_player.xml new file mode 100644 index 00000000..7c1ca724 --- /dev/null +++ b/app/src/main/res/color/button_player.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/bottom_player.xml b/app/src/main/res/layout/bottom_player.xml index 417cccf2..a52aec6d 100644 --- a/app/src/main/res/layout/bottom_player.xml +++ b/app/src/main/res/layout/bottom_player.xml @@ -93,18 +93,16 @@ android:layout_height="48dp" android:layout_marginStart="-2dp" android:layout_marginEnd="-2dp" + android:progressBackgroundTint="?attr/colorOutlineVariant" android:progressTint="?colorTertiary" android:secondaryProgressTint="?colorTertiary" - android:progressBackgroundTint="?attr/colorOutlineVariant" - android:progress="10" - android:secondaryProgress="20" android:thumb="@drawable/ic_thumb" android:thumbTint="?colorTertiary" />