home: reimplement speed dial overlay

The stock overlay is not sufficient for our needs, as:
1. It seemingly cannot be set up without missing certain touch areas or
disabling the touch area of the speed dial itself
2. The scrim can't be evenly applied everywhere in the app due to the
nested expore UI.

So, modify the speed dial to work without a scrim and reimplement the
overlay touch behavior manually.
This commit is contained in:
Alexander Capehart 2024-01-02 15:34:53 -07:00
parent afa73a2319
commit 8a75295d99
No known key found for this signature in database
GPG key ID: 37DBE3621FE9AD47
5 changed files with 52 additions and 12 deletions

View file

@ -21,6 +21,7 @@ package org.oxycblt.auxio.home
import android.os.Bundle import android.os.Bundle
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.MenuItem import android.view.MenuItem
import android.view.MotionEvent
import android.view.View import android.view.View
import androidx.activity.result.ActivityResultLauncher import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts import androidx.activity.result.contract.ActivityResultContracts
@ -77,6 +78,7 @@ import org.oxycblt.auxio.playback.PlaybackViewModel
import org.oxycblt.auxio.util.collect import org.oxycblt.auxio.util.collect
import org.oxycblt.auxio.util.collectImmediately import org.oxycblt.auxio.util.collectImmediately
import org.oxycblt.auxio.util.getColorCompat import org.oxycblt.auxio.util.getColorCompat
import org.oxycblt.auxio.util.isUnder
import org.oxycblt.auxio.util.lazyReflectedField import org.oxycblt.auxio.util.lazyReflectedField
import org.oxycblt.auxio.util.lazyReflectedMethod import org.oxycblt.auxio.util.lazyReflectedMethod
import org.oxycblt.auxio.util.logD import org.oxycblt.auxio.util.logD
@ -143,6 +145,21 @@ class HomeFragment :
} }
// --- UI SETUP --- // --- UI SETUP ---
binding.root.rootView.apply {
// Stock bottom sheet overlay won't work with our nested UI setup, have to replicate
// it ourselves.
findViewById<View>(R.id.main_scrim).setOnTouchListener { _, event ->
handleSpeedDialBoundaryTouch(event)
false
}
findViewById<View>(R.id.sheet_scrim).setOnTouchListener { _, event ->
handleSpeedDialBoundaryTouch(event)
false
}
}
binding.homeAppbar.addOnOffsetChangedListener(this) binding.homeAppbar.addOnOffsetChangedListener(this)
binding.homeNormalToolbar.apply { binding.homeNormalToolbar.apply {
setOnMenuItemClickListener(this@HomeFragment) setOnMenuItemClickListener(this@HomeFragment)
@ -589,6 +606,14 @@ class HomeFragment :
} }
} }
private fun handleSpeedDialBoundaryTouch(event: MotionEvent) {
val binding = requireBinding()
if (binding.homeNewPlaylistFab.isOpen &&
!binding.homeNewPlaylistFab.isUnder(event.x, event.y)) {
binding.homeNewPlaylistFab.close()
}
}
private fun handleShow(show: Show?) { private fun handleShow(show: Show?) {
when (show) { when (show) {
is Show.SongDetails -> { is Show.SongDetails -> {

View file

@ -24,7 +24,6 @@ import android.animation.AnimatorSet
import android.animation.ObjectAnimator import android.animation.ObjectAnimator
import android.content.Context import android.content.Context
import android.content.res.ColorStateList import android.content.res.ColorStateList
import android.graphics.Color
import android.graphics.drawable.Drawable import android.graphics.drawable.Drawable
import android.graphics.drawable.RotateDrawable import android.graphics.drawable.RotateDrawable
import android.os.Bundle import android.os.Bundle
@ -41,6 +40,7 @@ import androidx.core.view.setMargins
import androidx.core.view.updateLayoutParams import androidx.core.view.updateLayoutParams
import androidx.core.widget.TextViewCompat import androidx.core.widget.TextViewCompat
import androidx.interpolator.view.animation.FastOutSlowInInterpolator import androidx.interpolator.view.animation.FastOutSlowInInterpolator
import com.google.android.material.shape.MaterialShapeDrawable
import com.leinardi.android.speeddial.FabWithLabelView import com.leinardi.android.speeddial.FabWithLabelView
import com.leinardi.android.speeddial.SpeedDialActionItem import com.leinardi.android.speeddial.SpeedDialActionItem
import com.leinardi.android.speeddial.SpeedDialView import com.leinardi.android.speeddial.SpeedDialView
@ -48,6 +48,7 @@ import kotlin.math.roundToInt
import kotlinx.parcelize.Parcelize import kotlinx.parcelize.Parcelize
import org.oxycblt.auxio.R import org.oxycblt.auxio.R
import org.oxycblt.auxio.util.getAttrColorCompat import org.oxycblt.auxio.util.getAttrColorCompat
import org.oxycblt.auxio.util.getDimen
import org.oxycblt.auxio.util.getDimenPixels import org.oxycblt.auxio.util.getDimenPixels
/** /**
@ -64,6 +65,7 @@ import org.oxycblt.auxio.util.getDimenPixels
*/ */
class ThemedSpeedDialView : SpeedDialView { class ThemedSpeedDialView : SpeedDialView {
private var mainFabAnimator: Animator? = null private var mainFabAnimator: Animator? = null
private val spacingSmall = context.getDimenPixels(R.dimen.spacing_small)
constructor(context: Context) : super(context) constructor(context: Context) : super(context)
@ -174,7 +176,13 @@ class ThemedSpeedDialView : SpeedDialView {
val fabBackgroundColor = val fabBackgroundColor =
context.getAttrColorCompat(com.google.android.material.R.attr.colorSurface) context.getAttrColorCompat(com.google.android.material.R.attr.colorSurface)
val labelColor = context.getAttrColorCompat(android.R.attr.textColorSecondary) val labelColor = context.getAttrColorCompat(android.R.attr.textColorSecondary)
val labelBackgroundColor = Color.TRANSPARENT val labelBackgroundColor =
context.getAttrColorCompat(com.google.android.material.R.attr.colorSurface)
val labelStroke =
context.getAttrColorCompat(com.google.android.material.R.attr.colorOutline)
val labelElevation =
context.getDimen(com.google.android.material.R.dimen.m3_card_elevated_elevation)
val cornerRadius = context.getDimenPixels(R.dimen.spacing_medium)
val actionItem = val actionItem =
SpeedDialActionItem.Builder( SpeedDialActionItem.Builder(
actionItem.id, actionItem.id,
@ -184,7 +192,7 @@ class ThemedSpeedDialView : SpeedDialView {
.setFabImageTintColor(fabImageTintColor.defaultColor) .setFabImageTintColor(fabImageTintColor.defaultColor)
.setFabBackgroundColor(fabBackgroundColor.defaultColor) .setFabBackgroundColor(fabBackgroundColor.defaultColor)
.setLabelColor(labelColor.defaultColor) .setLabelColor(labelColor.defaultColor)
.setLabelBackgroundColor(labelBackgroundColor) .setLabelBackgroundColor(labelBackgroundColor.defaultColor)
.setLabelClickable(actionItem.isLabelClickable) .setLabelClickable(actionItem.isLabelClickable)
.setTheme(actionItem.theme) .setTheme(actionItem.theme)
.create() .create()
@ -199,7 +207,13 @@ class ThemedSpeedDialView : SpeedDialView {
labelBackground.apply { labelBackground.apply {
useCompatPadding = false useCompatPadding = false
setContentPadding(0, 0, 0, 0) setContentPadding(spacingSmall, spacingSmall, spacingSmall, spacingSmall)
background =
MaterialShapeDrawable.createWithElevationOverlay(context).apply {
fillColor = labelBackgroundColor
elevation = labelElevation
setCornerSize(cornerRadius.toFloat())
}
foreground = null foreground = null
(getChildAt(0) as TextView).apply { (getChildAt(0) as TextView).apply {
TextViewCompat.setTextAppearance(this, R.style.TextAppearance_Auxio_LabelLarge) TextViewCompat.setTextAppearance(this, R.style.TextAppearance_Auxio_LabelLarge)

View file

@ -17,6 +17,8 @@
app:navGraph="@navigation/inner" app:navGraph="@navigation/inner"
tools:layout="@layout/fragment_home" /> tools:layout="@layout/fragment_home" />
<View android:id="@+id/main_scrim" android:layout_height="match_parent" android:layout_width="match_parent"/>
<androidx.coordinatorlayout.widget.CoordinatorLayout <androidx.coordinatorlayout.widget.CoordinatorLayout
android:id="@+id/playback_sheet" android:id="@+id/playback_sheet"
android:layout_width="match_parent" android:layout_width="match_parent"
@ -72,6 +74,8 @@
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>
<View android:id="@+id/sheet_scrim" android:layout_height="match_parent" android:layout_width="match_parent"/>
</androidx.coordinatorlayout.widget.CoordinatorLayout> </androidx.coordinatorlayout.widget.CoordinatorLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout> </androidx.coordinatorlayout.widget.CoordinatorLayout>

View file

@ -156,11 +156,6 @@
app:layout_anchor="@id/home_content"> app:layout_anchor="@id/home_content">
<com.leinardi.android.speeddial.SpeedDialOverlayLayout
android:id="@+id/home_speed_dial_overlay"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<org.oxycblt.auxio.home.ThemedSpeedDialView <org.oxycblt.auxio.home.ThemedSpeedDialView
android:id="@+id/home_new_playlist_fab" android:id="@+id/home_new_playlist_fab"
android:layout_width="wrap_content" android:layout_width="wrap_content"
@ -171,8 +166,7 @@
android:gravity="bottom|end" android:gravity="bottom|end"
app:sdMainFabAnimationRotateAngle="135" app:sdMainFabAnimationRotateAngle="135"
app:sdMainFabClosedIconColor="@android:color/white" app:sdMainFabClosedIconColor="@android:color/white"
app:sdMainFabClosedSrc="@drawable/ic_add_24" app:sdMainFabClosedSrc="@drawable/ic_add_24"/>
app:sdOverlayLayout="@+id/home_speed_dial_overlay" />
<com.google.android.material.floatingactionbutton.FloatingActionButton <com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/home_shuffle_fab" android:id="@+id/home_shuffle_fab"
@ -184,5 +178,4 @@
</org.oxycblt.auxio.home.EdgeFrameLayout> </org.oxycblt.auxio.home.EdgeFrameLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout> </androidx.coordinatorlayout.widget.CoordinatorLayout>

View file

@ -18,6 +18,8 @@
app:navGraph="@navigation/inner" app:navGraph="@navigation/inner"
tools:layout="@layout/fragment_home" /> tools:layout="@layout/fragment_home" />
<View android:id="@+id/main_scrim" android:layout_height="match_parent" android:layout_width="match_parent"/>
<androidx.coordinatorlayout.widget.CoordinatorLayout <androidx.coordinatorlayout.widget.CoordinatorLayout
android:id="@+id/playback_sheet" android:id="@+id/playback_sheet"
style="@style/Widget.Auxio.DisableDropShadows" style="@style/Widget.Auxio.DisableDropShadows"
@ -81,6 +83,8 @@
</LinearLayout> </LinearLayout>
<View android:id="@+id/sheet_scrim" android:layout_height="match_parent" android:layout_width="match_parent"/>
</androidx.coordinatorlayout.widget.CoordinatorLayout> </androidx.coordinatorlayout.widget.CoordinatorLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout> </androidx.coordinatorlayout.widget.CoordinatorLayout>