ui: clean up colors

Further clean up coloring, adding new selectors to cut down on resource
duplication and to simplify logic in general.
This commit is contained in:
OxygenCobalt 2021-09-04 22:46:11 -06:00
parent 34367b3bae
commit 0fc8f1cd02
No known key found for this signature in database
GPG key ID: 37DBE3621FE9AD47
18 changed files with 44 additions and 83 deletions

View file

@ -29,15 +29,12 @@ import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
import androidx.navigation.fragment.findNavController
import org.oxycblt.auxio.R
import org.oxycblt.auxio.accent.Accent
import org.oxycblt.auxio.databinding.FragmentPlaybackBinding
import org.oxycblt.auxio.detail.DetailViewModel
import org.oxycblt.auxio.playback.state.LoopMode
import org.oxycblt.auxio.ui.memberBinding
import org.oxycblt.auxio.util.applyEdge
import org.oxycblt.auxio.util.logD
import org.oxycblt.auxio.util.resolveDrawable
import org.oxycblt.auxio.util.resolveStateList
/**
* A [Fragment] that displays more information about the song, along with more media controls.
@ -48,7 +45,7 @@ class PlaybackFragment : Fragment(), SeekBar.OnSeekBarChangeListener {
private val playbackModel: PlaybackViewModel by activityViewModels()
private val detailModel: DetailViewModel by activityViewModels()
private val binding by memberBinding(FragmentPlaybackBinding::inflate) {
playbackSong.isSelected = false
playbackSong.isSelected = false // Clear marquee to prevent a memory leak
}
override fun onCreateView(
@ -56,14 +53,6 @@ class PlaybackFragment : Fragment(), SeekBar.OnSeekBarChangeListener {
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
val normalTextColor = binding.playbackDurationCurrent.currentTextColor
val accentColor = Accent.get().getStateList(requireContext())
val controlColor = R.color.control.resolveStateList(requireContext())
// Can't set the tint of a MenuItem below Android 8, so use icons instead.
val iconQueueActive = R.drawable.ic_queue.resolveDrawable(requireContext())
val iconQueueInactive = R.drawable.ic_queue_inactive.resolveDrawable(requireContext())
val queueItem: MenuItem
// --- UI SETUP ---
@ -102,6 +91,7 @@ class PlaybackFragment : Fragment(), SeekBar.OnSeekBarChangeListener {
binding.playbackSeekBar.setOnSeekBarChangeListener(this)
// --- VIEWMODEL SETUP --
playbackModel.song.observe(viewLifecycleOwner) { song ->
if (song != null) {
logD("Updating song display to ${song.name}.")
@ -120,32 +110,17 @@ class PlaybackFragment : Fragment(), SeekBar.OnSeekBarChangeListener {
}
playbackModel.loopMode.observe(viewLifecycleOwner) { loopMode ->
when (loopMode) {
LoopMode.NONE -> {
binding.playbackLoop.imageTintList = controlColor
binding.playbackLoop.setImageResource(R.drawable.ic_loop)
}
LoopMode.ALL -> {
binding.playbackLoop.imageTintList = accentColor
binding.playbackLoop.setImageResource(R.drawable.ic_loop)
}
LoopMode.TRACK -> {
binding.playbackLoop.imageTintList = accentColor
binding.playbackLoop.setImageResource(R.drawable.ic_loop_one)
}
else -> return@observe
val resId = when (loopMode) {
LoopMode.NONE, null -> R.drawable.ic_loop
LoopMode.ALL -> R.drawable.ic_loop_on
LoopMode.TRACK -> R.drawable.ic_loop_one
}
binding.playbackLoop.setImageResource(resId)
}
playbackModel.isSeeking.observe(viewLifecycleOwner) { isSeeking ->
if (isSeeking) {
binding.playbackDurationCurrent.setTextColor(accentColor)
} else {
binding.playbackDurationCurrent.setTextColor(normalTextColor)
}
binding.playbackDurationCurrent.isActivated = isSeeking
}
playbackModel.positionAsProgress.observe(viewLifecycleOwner) { pos ->
@ -155,27 +130,11 @@ class PlaybackFragment : Fragment(), SeekBar.OnSeekBarChangeListener {
}
playbackModel.nextItemsInQueue.observe(viewLifecycleOwner) { nextQueue ->
val userQueue = playbackModel.userQueue.value!!
if (userQueue.isEmpty() && nextQueue.isEmpty()) {
queueItem.icon = iconQueueInactive
queueItem.isEnabled = false
} else {
queueItem.icon = iconQueueActive
queueItem.isEnabled = true
}
updateQueueIcon(queueItem)
}
playbackModel.userQueue.observe(viewLifecycleOwner) { userQueue ->
val nextQueue = playbackModel.nextItemsInQueue.value!!
if (userQueue.isEmpty() && nextQueue.isEmpty()) {
queueItem.icon = iconQueueInactive
queueItem.isEnabled = false
} else {
queueItem.icon = iconQueueActive
queueItem.isEnabled = true
}
updateQueueIcon(queueItem)
}
playbackModel.isPlaying.observe(viewLifecycleOwner) { isPlaying ->
@ -193,6 +152,15 @@ class PlaybackFragment : Fragment(), SeekBar.OnSeekBarChangeListener {
return binding.root
}
private fun updateQueueIcon(queueItem: MenuItem) {
val userQueue = playbackModel.userQueue.value!!
val nextQueue = playbackModel.nextItemsInQueue.value!!
// The queue icon uses a selector that will automatically tint the icon as active or
// inactive. We just need to set the flag.
queueItem.isEnabled = !(userQueue.isEmpty() && nextQueue.isEmpty())
}
// --- SEEK CALLBACKS ---
override fun onProgressChanged(seekBar: SeekBar, progress: Int, fromUser: Boolean) {

View file

@ -75,7 +75,7 @@ fun RecyclerView.applySpans(shouldBeFullWidth: ((Int) -> Boolean)? = null) {
*/
fun ImageButton.disable() {
if (isEnabled) {
imageTintList = R.color.inactive.resolveStateList(context)
imageTintList = ContextCompat.getColorStateList(context, R.color.overlay_disabled)
isEnabled = false
}
}

View file

@ -129,7 +129,7 @@ fun createFullWidget(context: Context, state: WidgetState): RemoteViews {
val loopRes = when (state.loopMode) {
LoopMode.NONE -> R.drawable.ic_loop
LoopMode.ALL -> R.drawable.ic_loop_tinted
LoopMode.ALL -> R.drawable.ic_loop_on
LoopMode.TRACK -> R.drawable.ic_loop_one
}

View file

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="?attr/colorOnSurface" android:alpha="0.24" android:state_enabled="false" />
<item android:color="?attr/colorControlNormal" />
</selector>

View file

@ -2,5 +2,5 @@
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="?attr/colorAccent"
android:state_activated="true" />
<item android:color="?android:attr/textColorTertiary" />
<item android:color="?android:attr/textColorSecondary" />
</selector>

View file

@ -2,7 +2,7 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="?attr/colorControlNormal"
android:tint="@color/overlay_disabled"
android:viewportWidth="24"
android:viewportHeight="24">
<path

View file

@ -1,11 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="@color/inactive"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/white"
android:pathData="M15 6H3v2h12V6zm0 4H3v2h12v-2zM3 16h8v-2H3v2zM17 6v8.18C16.69 14.07 16.35 14 16 14c-1.66 0-3 1.34-3 3s1.34 3 3 3 3-1.34 3-3V8h3V6h-5z" />
</vector>

View file

@ -1,9 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="?attr/colorControlHighlight">
android:color="@color/mtrl_btn_ripple_color">
<item>
<shape android:shape="oval"
android:tint="@color/sel_accent_active">
android:tint="@color/sel_accented">
<solid android:color="@android:color/white" />
</shape>
</item>

View file

@ -116,6 +116,7 @@
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/spacing_mid_large"
android:text="@{playbackModel.formattedPosition}"
android:textColor="@color/sel_accented_secondary"
app:layout_constraintBottom_toTopOf="@+id/playback_play_pause"
app:layout_constraintStart_toEndOf="@+id/playback_cover"
app:layout_constraintTop_toBottomOf="@+id/playback_seek_bar"
@ -183,7 +184,7 @@
android:contentDescription="@string/desc_shuffle"
android:onClick="@{() -> playbackModel.invertShuffleStatus()}"
android:src="@drawable/ic_shuffle"
app:tint="@color/sel_accent_active"
app:tint="@color/sel_accented"
app:layout_constraintBottom_toBottomOf="@+id/playback_skip_next"
app:layout_constraintEnd_toEndOf="@+id/playback_song_duration"
app:layout_constraintTop_toTopOf="@+id/playback_skip_next" />

View file

@ -117,6 +117,7 @@
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/spacing_mid_large"
android:text="@{playbackModel.formattedPosition}"
android:textColor="@color/sel_accented_secondary"
app:layout_constraintBottom_toTopOf="@+id/playback_play_pause"
app:layout_constraintStart_toEndOf="@+id/playback_cover"
app:layout_constraintTop_toBottomOf="@+id/playback_seek_bar"
@ -184,7 +185,7 @@
android:contentDescription="@string/desc_shuffle"
android:onClick="@{() -> playbackModel.invertShuffleStatus()}"
android:src="@drawable/ic_shuffle"
app:tint="@color/sel_accent_active"
app:tint="@color/sel_accented"
app:layout_constraintBottom_toBottomOf="@+id/playback_skip_next"
app:layout_constraintStart_toEndOf="@+id/playback_skip_next"
app:layout_constraintTop_toTopOf="@+id/playback_skip_next" />

View file

@ -104,6 +104,7 @@
android:layout_marginStart="@dimen/spacing_mid_huge"
android:layout_marginBottom="@dimen/spacing_medium"
android:text="@{playbackModel.formattedPosition}"
android:textColor="@color/sel_accented_secondary"
app:layout_constraintBottom_toTopOf="@+id/playback_play_pause"
app:layout_constraintStart_toStartOf="parent"
tools:text="11:38" />
@ -171,7 +172,7 @@
android:contentDescription="@string/desc_shuffle"
android:onClick="@{() -> playbackModel.invertShuffleStatus()}"
android:src="@drawable/ic_shuffle"
app:tint="@color/sel_accent_active"
app:tint="@color/sel_accented"
app:layout_constraintBottom_toBottomOf="@+id/playback_skip_next"
app:layout_constraintStart_toEndOf="@+id/playback_skip_next"
app:layout_constraintTop_toTopOf="@+id/playback_skip_next" />

View file

@ -101,6 +101,7 @@
android:layout_marginStart="@dimen/spacing_mid_large"
android:layout_marginBottom="@dimen/spacing_medium"
android:text="@{playbackModel.formattedPosition}"
android:textColor="@color/sel_accented_secondary"
app:layout_constraintBottom_toTopOf="@+id/playback_play_pause"
app:layout_constraintStart_toStartOf="parent"
tools:text="11:38" />
@ -167,7 +168,7 @@
android:contentDescription="@string/desc_shuffle"
android:onClick="@{() -> playbackModel.invertShuffleStatus()}"
android:src="@drawable/ic_shuffle"
app:tint="@color/sel_accent_active"
app:tint="@color/sel_accented"
app:layout_constraintBottom_toBottomOf="@+id/playback_skip_next"
app:layout_constraintEnd_toEndOf="@+id/playback_song_duration"
app:layout_constraintTop_toTopOf="@+id/playback_skip_next" />

View file

@ -24,7 +24,7 @@
android:text="@{String.valueOf(song.track)}"
android:textAlignment="center"
android:textAppearance="?android:attr/textAppearanceListItem"
android:textColor="@color/sel_accented_track"
android:textColor="@color/sel_accented_secondary"
android:textSize="@dimen/text_size_large"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"

View file

@ -1,7 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="surface">@color/surface_night</color>
<color name="inactive">#404040</color>
<color name="surface">#202124</color>
<color name="control">#ffffff</color>
<color name="nav_bar">#01151515</color>

View file

@ -1,12 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="surface_day">#fafafa</color>
<color name="surface_night">#202124</color>
<color name="surface">#fafafa</color>
<color name="surface_black">@android:color/black</color>
<color name="surface">@color/surface_day</color>
<color name="control">#202020</color>
<color name="inactive">#c4c4c4</color>
<color name="nav_bar">#01fafafa</color>
<!--

View file

@ -26,7 +26,7 @@
<style name="Widget.ProgressBar.Compact" parent="@style/Widget.AppCompat.ProgressBar.Horizontal">
<item name="android:layout_width">match_parent</item>
<item name="android:layout_height">@dimen/size_stroke_large</item>
<item name="android:progressBackgroundTint">?attr/colorControlNormal</item>
<item name="android:progressBackgroundTint">?attr/colorAccent</item>
<item name="android:progressTint">?attr/colorAccent</item>
</style>
@ -35,7 +35,7 @@
<item name="android:focusable">true</item>
<item name="android:paddingStart">@dimen/spacing_mid_large</item>
<item name="android:paddingEnd">@dimen/spacing_mid_large</item>
<item name="android:progressBackgroundTint">?android:attr/colorControlNormal</item>
<item name="android:progressBackgroundTint">?attr/colorAccent</item>
<item name="android:progressTint">?attr/colorAccent</item>
<item name="android:splitTrack">false</item>
<item name="android:thumbOffset">@dimen/offset_thumb</item>