ui: add image playing indicator
Add a playing indicator to cover art. This is simply to improve the general aestethics of this view. Of course, the current way I implement this is incredibly stupid and I plan to replace it.
This commit is contained in:
parent
1d66907862
commit
ffe7298665
8 changed files with 51 additions and 16 deletions
|
@ -10,6 +10,8 @@
|
|||
- The toolbar in the home UI now collapses when scrolling
|
||||
- The toolbar layout is now consistent with Material Design 3
|
||||
- Genre parsing now handles multiple integer values and cover/remix indicators (May wipe playback state)
|
||||
|
||||
#### What's Fixed
|
||||
- Playback bar now picks the larger inset in case that gesture inset is missing [#149]
|
||||
|
||||
#### Dev/Meta
|
||||
|
|
|
@ -74,8 +74,7 @@ abstract class BaseFetcher : Fetcher {
|
|||
fetchMediaStoreCovers(context, album)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
logW("Unable to extract album art due to an error")
|
||||
logW(e.stackTraceToString())
|
||||
logW("Unable to extract album art due to an error: $e")
|
||||
null
|
||||
}
|
||||
}
|
||||
|
|
|
@ -54,7 +54,7 @@ constructor(
|
|||
FrameLayout(context, attrs, defStyleAttr),
|
||||
Slider.OnSliderTouchListener,
|
||||
Slider.OnChangeListener {
|
||||
private val binding = ViewSeekBarBinding.inflate(context.inflater, this, true)
|
||||
private val binding = ViewSeekBarBinding.inflate(context.inflater, this)
|
||||
|
||||
init {
|
||||
binding.seekBarSlider.addOnSliderTouchListener(this)
|
||||
|
|
|
@ -29,6 +29,7 @@ import androidx.annotation.StringRes
|
|||
import androidx.appcompat.widget.AppCompatImageView
|
||||
import androidx.core.graphics.drawable.DrawableCompat
|
||||
import coil.dispose
|
||||
import coil.drawable.CrossfadeDrawable
|
||||
import coil.load
|
||||
import com.google.android.material.shape.MaterialShapeDrawable
|
||||
import org.oxycblt.auxio.R
|
||||
|
@ -50,19 +51,18 @@ import org.oxycblt.auxio.util.getDrawableSafe
|
|||
* of the view size, and corner radius application depending on user preference.
|
||||
* @author OxygenCobalt
|
||||
*
|
||||
* TODO: Rework this layout into a total ViewGroup that enables more customization + an indicator
|
||||
* TODO: I'll need to make it a whole ViewGroup eventually
|
||||
*/
|
||||
class StyledImageView
|
||||
@JvmOverloads
|
||||
constructor(context: Context, attrs: AttributeSet? = null, @AttrRes defStyleAttr: Int = 0) :
|
||||
AppCompatImageView(context, attrs, defStyleAttr) {
|
||||
private var cornerRadius = 0f
|
||||
private var indicator = StyledDrawable(context, R.drawable.ic_equalizer)
|
||||
|
||||
init {
|
||||
val styledAttrs = context.obtainStyledAttributes(attrs, R.styleable.StyledImageView)
|
||||
|
||||
cornerRadius = styledAttrs.getDimension(R.styleable.StyledImageView_cornerRadius, 0f)
|
||||
|
||||
styledAttrs.recycle()
|
||||
|
||||
// Use clipToOutline and a background drawable to crop images. While Coil's transformation
|
||||
|
@ -95,19 +95,35 @@ constructor(context: Context, attrs: AttributeSet? = null, @AttrRes defStyleAttr
|
|||
}
|
||||
}
|
||||
|
||||
override fun onDraw(canvas: Canvas) {
|
||||
super.onDraw(canvas)
|
||||
if (isActivated) {
|
||||
// We can't modify the view alpha since that would change the background opacity,
|
||||
// but we also can't modify the image alpha since that breaks CrossfadeDrawable.
|
||||
// Instead, we just draw the background again when activated in order to obscure
|
||||
// the actual image, and then draw the indicator. The only other option is to make
|
||||
// a proper ViewGroup, and I really don't want that.
|
||||
val src = drawable?.let { if (it is CrossfadeDrawable) it.end else it }
|
||||
background.alpha = if (src is StyledDrawable) 255 else 128
|
||||
background.draw(canvas)
|
||||
background.alpha = 255
|
||||
indicator.draw(canvas)
|
||||
}
|
||||
}
|
||||
|
||||
/** Bind the album cover for a [song]. */
|
||||
fun bind(song: Song) = load(song, R.drawable.ic_song, R.string.desc_album_cover)
|
||||
fun bind(song: Song) = loadImpl(song, R.drawable.ic_song, R.string.desc_album_cover)
|
||||
|
||||
/** Bind the album cover for an [album]. */
|
||||
fun bind(album: Album) = load(album, R.drawable.ic_album, R.string.desc_album_cover)
|
||||
fun bind(album: Album) = loadImpl(album, R.drawable.ic_album, R.string.desc_album_cover)
|
||||
|
||||
/** Bind the image for an [artist] */
|
||||
fun bind(artist: Artist) = load(artist, R.drawable.ic_artist, R.string.desc_artist_image)
|
||||
fun bind(artist: Artist) = loadImpl(artist, R.drawable.ic_artist, R.string.desc_artist_image)
|
||||
|
||||
/** Bind the image for a [genre] */
|
||||
fun bind(genre: Genre) = load(genre, R.drawable.ic_genre, R.string.desc_genre_image)
|
||||
fun bind(genre: Genre) = loadImpl(genre, R.drawable.ic_genre, R.string.desc_genre_image)
|
||||
|
||||
private fun <T : Music> load(music: T, @DrawableRes error: Int, @StringRes desc: Int) {
|
||||
private fun <T : Music> loadImpl(music: T, @DrawableRes error: Int, @StringRes desc: Int) {
|
||||
dispose()
|
||||
load(music) {
|
||||
error(StyledDrawable(context, error))
|
||||
|
|
5
app/src/main/res/color/sel_track_cover.xml
Normal file
5
app/src/main/res/color/sel_track_cover.xml
Normal 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="@android:color/transparent" android:state_activated="true" />
|
||||
<item android:color="?attr/colorSurfaceInverse" />
|
||||
</selector>
|
11
app/src/main/res/drawable/ic_equalizer.xml
Normal file
11
app/src/main/res/drawable/ic_equalizer.xml
Normal file
|
@ -0,0 +1,11 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24"
|
||||
android:tint="?attr/colorControlNormal">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M10,20h4L14,4h-4v16zM4,20h4v-8L4,12v8zM16,9v11h4L20,9h-4z"/>
|
||||
</vector>
|
|
@ -8,7 +8,8 @@
|
|||
<!--
|
||||
We don't want to show an album cover, but we still want the spacing of this song
|
||||
to be alike to other songs. So, add a pastel-ish background to each track number
|
||||
view. The way we do this is odd, but it's designed this way-->
|
||||
view. The way we do this is odd, but it's designed this way.
|
||||
-->
|
||||
|
||||
<org.oxycblt.auxio.ui.StyledImageView
|
||||
android:id="@+id/song_track_bg"
|
||||
|
@ -27,7 +28,7 @@
|
|||
android:maxLines="1"
|
||||
android:textAlignment="center"
|
||||
android:textAppearance="@style/TextAppearance.Auxio.BodyLarge"
|
||||
android:textColor="@color/sel_on_cover_bg"
|
||||
android:textColor="@color/sel_track_cover"
|
||||
app:autoSizeMaxTextSize="@dimen/text_size_track_number_max"
|
||||
app:autoSizeMinTextSize="@dimen/text_size_track_number_min"
|
||||
app:autoSizeStepGranularity="@dimen/text_size_track_number_step"
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<merge xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
android:layout_height="wrap_content"
|
||||
tools:parentTag="android.widget.FrameLayout">
|
||||
|
||||
<com.google.android.material.slider.Slider
|
||||
android:id="@+id/seek_bar_slider"
|
||||
|
@ -41,4 +42,4 @@
|
|||
app:layout_constraintTop_toBottomOf="@+id/playback_seek_bar"
|
||||
tools:text="16:16" />
|
||||
|
||||
</FrameLayout>
|
||||
</merge>
|
Loading…
Reference in a new issue