image: add selection indicator
Add a selection indicator to ImageGroup.
This commit is contained in:
parent
0598409ca5
commit
abd51ad16e
4 changed files with 66 additions and 14 deletions
|
@ -21,7 +21,6 @@ import android.os.Bundle
|
|||
import android.text.format.Formatter
|
||||
import android.view.LayoutInflater
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.core.view.isGone
|
||||
import androidx.core.view.isInvisible
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import androidx.navigation.fragment.navArgs
|
||||
|
|
|
@ -20,16 +20,21 @@ package org.oxycblt.auxio.image
|
|||
import android.annotation.SuppressLint
|
||||
import android.content.Context
|
||||
import android.util.AttributeSet
|
||||
import android.view.Gravity
|
||||
import android.view.View
|
||||
import android.widget.FrameLayout
|
||||
import android.widget.ImageView
|
||||
import androidx.annotation.AttrRes
|
||||
import androidx.core.view.updateMarginsRelative
|
||||
import com.google.android.material.shape.MaterialShapeDrawable
|
||||
import org.oxycblt.auxio.R
|
||||
import org.oxycblt.auxio.music.Album
|
||||
import org.oxycblt.auxio.music.Artist
|
||||
import org.oxycblt.auxio.music.Genre
|
||||
import org.oxycblt.auxio.music.Song
|
||||
import org.oxycblt.auxio.util.getAttrColorCompat
|
||||
import org.oxycblt.auxio.util.getColorCompat
|
||||
import org.oxycblt.auxio.util.getDimenSize
|
||||
|
||||
/**
|
||||
* Effectively a super-charged [StyledImageView].
|
||||
|
@ -51,7 +56,8 @@ constructor(context: Context, attrs: AttributeSet? = null, @AttrRes defStyleAttr
|
|||
private val cornerRadius: Float
|
||||
private val inner: StyledImageView
|
||||
private var customView: View? = null
|
||||
private val indicator: IndicatorView
|
||||
private val playingIndicator: IndicatorView
|
||||
private val selectionIndicator: ImageView
|
||||
|
||||
init {
|
||||
// Android wants you to make separate attributes for each view type, but will
|
||||
|
@ -62,7 +68,14 @@ constructor(context: Context, attrs: AttributeSet? = null, @AttrRes defStyleAttr
|
|||
styledAttrs.recycle()
|
||||
|
||||
inner = StyledImageView(context, attrs)
|
||||
indicator = IndicatorView(context).apply { cornerRadius = this@ImageGroup.cornerRadius }
|
||||
playingIndicator =
|
||||
IndicatorView(context).apply { cornerRadius = this@ImageGroup.cornerRadius }
|
||||
selectionIndicator =
|
||||
ImageView(context).apply {
|
||||
imageTintList = context.getAttrColorCompat(R.attr.colorOnPrimary)
|
||||
setImageResource(R.drawable.ic_check_20)
|
||||
setBackgroundResource(R.drawable.ui_selection_badge_bg)
|
||||
}
|
||||
|
||||
addView(inner)
|
||||
}
|
||||
|
@ -83,44 +96,65 @@ constructor(context: Context, attrs: AttributeSet? = null, @AttrRes defStyleAttr
|
|||
}
|
||||
}
|
||||
|
||||
addView(indicator)
|
||||
addView(playingIndicator)
|
||||
addView(
|
||||
selectionIndicator,
|
||||
LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT).apply {
|
||||
gravity = Gravity.BOTTOM or Gravity.END
|
||||
val spacing = context.getDimenSize(R.dimen.spacing_tiny)
|
||||
updateMarginsRelative(bottom = spacing, end = spacing)
|
||||
})
|
||||
}
|
||||
|
||||
override fun onAttachedToWindow() {
|
||||
super.onAttachedToWindow()
|
||||
invalidateIndicator()
|
||||
invalidateAlpha()
|
||||
invalidatePlayingIndicator()
|
||||
}
|
||||
|
||||
override fun setActivated(activated: Boolean) {
|
||||
super.setActivated(activated)
|
||||
invalidateIndicator()
|
||||
invalidateAlpha()
|
||||
invalidatePlayingIndicator()
|
||||
}
|
||||
|
||||
override fun setEnabled(enabled: Boolean) {
|
||||
super.setEnabled(enabled)
|
||||
invalidateIndicator()
|
||||
invalidateAlpha()
|
||||
invalidatePlayingIndicator()
|
||||
}
|
||||
|
||||
override fun setSelected(selected: Boolean) {
|
||||
super.setSelected(selected)
|
||||
invalidateSelectionIndicator()
|
||||
}
|
||||
|
||||
var isPlaying: Boolean
|
||||
get() = indicator.isPlaying
|
||||
get() = playingIndicator.isPlaying
|
||||
set(value) {
|
||||
indicator.isPlaying = value
|
||||
playingIndicator.isPlaying = value
|
||||
}
|
||||
|
||||
private fun invalidateIndicator() {
|
||||
private fun invalidateAlpha() {
|
||||
alpha = if (isActivated || isEnabled) 1f else 0.5f
|
||||
}
|
||||
|
||||
private fun invalidatePlayingIndicator() {
|
||||
if (isActivated) {
|
||||
alpha = 1f
|
||||
customView?.alpha = 0f
|
||||
inner.alpha = 0f
|
||||
indicator.alpha = 1f
|
||||
playingIndicator.alpha = 1f
|
||||
} else {
|
||||
alpha = if (isEnabled) 1f else 0.5f
|
||||
customView?.alpha = 1f
|
||||
inner.alpha = 1f
|
||||
indicator.alpha = 0f
|
||||
playingIndicator.alpha = 0f
|
||||
}
|
||||
}
|
||||
|
||||
private fun invalidateSelectionIndicator() {
|
||||
selectionIndicator.alpha = if (isSelected) 1f else 0f
|
||||
}
|
||||
|
||||
fun bind(song: Song) {
|
||||
inner.bind(song)
|
||||
contentDescription =
|
||||
|
|
10
app/src/main/res/drawable/ic_check_20.xml
Normal file
10
app/src/main/res/drawable/ic_check_20.xml
Normal file
|
@ -0,0 +1,10 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="20dp"
|
||||
android:height="20dp"
|
||||
android:viewportWidth="20"
|
||||
android:viewportHeight="20"
|
||||
android:tint="?attr/colorControlNormal">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M8.229,14.062 L4.708,10.521 5.75,9.479 8.229,11.938 14.25,5.938 15.292,7Z"/>
|
||||
</vector>
|
9
app/src/main/res/drawable/ui_selection_badge_bg.xml
Normal file
9
app/src/main/res/drawable/ui_selection_badge_bg.xml
Normal file
|
@ -0,0 +1,9 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="oval"
|
||||
android:tint="?attr/colorPrimary">
|
||||
|
||||
<size
|
||||
android:width="20dp"
|
||||
android:height="20dp" />
|
||||
</shape>
|
Loading…
Reference in a new issue