ui: animate selection
Animate the check mark and background change when a item is selected. This produces a nicer UX overall. If possible, I'm planning to also port this to the other indicators in ImageGroup, albeit doing that is signifigantly harder.
This commit is contained in:
parent
a02490ae18
commit
f5ec295b2c
6 changed files with 45 additions and 9 deletions
|
@ -26,7 +26,9 @@ import android.widget.FrameLayout
|
|||
import android.widget.ImageView
|
||||
import androidx.annotation.AttrRes
|
||||
import androidx.core.view.updateMarginsRelative
|
||||
import androidx.transition.TransitionManager
|
||||
import com.google.android.material.shape.MaterialShapeDrawable
|
||||
import com.google.android.material.transition.MaterialFade
|
||||
import org.oxycblt.auxio.R
|
||||
import org.oxycblt.auxio.music.Album
|
||||
import org.oxycblt.auxio.music.Artist
|
||||
|
@ -142,6 +144,7 @@ constructor(context: Context, attrs: AttributeSet? = null, @AttrRes defStyleAttr
|
|||
|
||||
private fun invalidatePlayingIndicator() {
|
||||
if (isSelected) {
|
||||
// TODO: Animate the other indicators?
|
||||
customView?.alpha = 0f
|
||||
inner.alpha = 0f
|
||||
playingIndicator.alpha = 1f
|
||||
|
@ -153,7 +156,26 @@ constructor(context: Context, attrs: AttributeSet? = null, @AttrRes defStyleAttr
|
|||
}
|
||||
|
||||
private fun invalidateSelectionIndicator() {
|
||||
selectionIndicator.alpha = if (isActivated) 1f else 0f
|
||||
val targetVis: Int
|
||||
val targetDuration: Long
|
||||
|
||||
if (isActivated) {
|
||||
targetVis = VISIBLE
|
||||
targetDuration = 150L
|
||||
} else {
|
||||
targetVis = INVISIBLE
|
||||
targetDuration = 84L
|
||||
}
|
||||
|
||||
if (selectionIndicator.visibility == targetVis) {
|
||||
return
|
||||
}
|
||||
|
||||
TransitionManager.beginDelayedTransition(this, MaterialFade().apply {
|
||||
duration = targetDuration
|
||||
})
|
||||
|
||||
selectionIndicator.visibility = targetVis
|
||||
}
|
||||
|
||||
fun bind(song: Song) {
|
||||
|
|
|
@ -43,7 +43,6 @@ class SongViewHolder private constructor(private val binding: ItemSongBinding) :
|
|||
binding.songName.text = item.resolveName(binding.context)
|
||||
binding.songInfo.text = item.resolveArtistContents(binding.context)
|
||||
|
||||
binding.songAlbumCover.setOnClickListener { listener.onSelect(item) }
|
||||
binding.songMenu.setOnClickListener { listener.onOpenMenu(item, it) }
|
||||
binding.root.apply {
|
||||
setOnClickListener { listener.onItemClick(item) }
|
||||
|
@ -88,7 +87,6 @@ class AlbumViewHolder private constructor(private val binding: ItemParentBinding
|
|||
binding.parentName.text = item.resolveName(binding.context)
|
||||
binding.parentInfo.text = item.resolveArtistContents(binding.context)
|
||||
|
||||
binding.parentImage.setOnClickListener { listener.onSelect(item) }
|
||||
binding.parentMenu.setOnClickListener { listener.onOpenMenu(item, it) }
|
||||
binding.root.apply {
|
||||
setOnClickListener { listener.onItemClick(item) }
|
||||
|
@ -145,7 +143,6 @@ class ArtistViewHolder private constructor(private val binding: ItemParentBindin
|
|||
binding.context.getPlural(R.plurals.fmt_album_count, item.albums.size)
|
||||
}
|
||||
|
||||
binding.parentImage.setOnClickListener { listener.onSelect(item) }
|
||||
binding.parentMenu.setOnClickListener { listener.onOpenMenu(item, it) }
|
||||
binding.root.apply {
|
||||
setOnClickListener { listener.onItemClick(item) }
|
||||
|
@ -196,7 +193,6 @@ class GenreViewHolder private constructor(private val binding: ItemParentBinding
|
|||
binding.context.getPlural(R.plurals.fmt_artist_count, item.artists.size),
|
||||
binding.context.getPlural(R.plurals.fmt_song_count, item.songs.size))
|
||||
|
||||
binding.parentImage.setOnClickListener { listener.onSelect(item) }
|
||||
binding.parentMenu.setOnClickListener { listener.onOpenMenu(item, it) }
|
||||
binding.root.apply {
|
||||
setOnClickListener { listener.onItemClick(item) }
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:alpha="0.12" android:color="?attr/colorPrimary" android:state_activated="true"/>
|
||||
<item android:color="?attr/colorSurface" />
|
||||
</selector>
|
19
app/src/main/res/drawable/sel_item_ripple_bg.xml
Normal file
19
app/src/main/res/drawable/sel_item_ripple_bg.xml
Normal file
|
@ -0,0 +1,19 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<animated-selector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:enterFadeDuration="150"
|
||||
android:exitFadeDuration="150">
|
||||
|
||||
<item
|
||||
android:id="@+id/pressed"
|
||||
android:state_activated="true">
|
||||
<shape android:shape="rectangle">
|
||||
<solid android:color="@color/sel_item_activated_bg" />
|
||||
</shape>
|
||||
</item>
|
||||
<item
|
||||
android:id="@+id/def">
|
||||
<shape android:shape="rectangle">
|
||||
<solid android:color="@color/sel_item_activated_bg" />
|
||||
</shape>
|
||||
</item>
|
||||
</animated-selector>
|
|
@ -1,5 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:drawable="@color/sel_activatable_background" />
|
||||
<item android:drawable="@drawable/sel_item_ripple_bg" />
|
||||
<item android:drawable="?attr/selectableItemBackground" />
|
||||
</layer-list>
|
|
@ -5,9 +5,9 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:paddingStart="@dimen/spacing_mid_large"
|
||||
android:paddingStart="@dimen/spacing_large"
|
||||
android:paddingTop="@dimen/spacing_medium"
|
||||
android:paddingEnd="@dimen/spacing_mid_large"
|
||||
android:paddingEnd="@dimen/spacing_large"
|
||||
android:paddingBottom="@dimen/spacing_medium">
|
||||
|
||||
<org.oxycblt.auxio.image.ImageGroup
|
||||
|
|
Loading…
Reference in a new issue