ui: tweak bottom sheet dialog transitions

Use a native slide animation for entering/editing bottom sheet dialogs,
which looks a good amount nicer overall.
This commit is contained in:
Alexander Capehart 2023-07-11 15:39:58 -06:00
parent 32a0d97e5d
commit 9111a6eec7
No known key found for this signature in database
GPG key ID: 37DBE3621FE9AD47
4 changed files with 77 additions and 9 deletions

View file

@ -18,13 +18,16 @@
package org.oxycblt.auxio.ui package org.oxycblt.auxio.ui
import android.content.Context
import android.os.Bundle import android.os.Bundle
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.appcompat.app.AlertDialog import androidx.annotation.StyleRes
import androidx.fragment.app.DialogFragment import androidx.fragment.app.DialogFragment
import androidx.viewbinding.ViewBinding import androidx.viewbinding.ViewBinding
import com.google.android.material.bottomsheet.BottomSheetBehavior
import com.google.android.material.bottomsheet.BottomSheetDialog
import com.google.android.material.bottomsheet.BottomSheetDialogFragment import com.google.android.material.bottomsheet.BottomSheetDialogFragment
import org.oxycblt.auxio.util.logD import org.oxycblt.auxio.util.logD
import org.oxycblt.auxio.util.unlikelyToBeNull import org.oxycblt.auxio.util.unlikelyToBeNull
@ -39,13 +42,8 @@ abstract class ViewBindingBottomSheetDialogFragment<VB : ViewBinding> :
BottomSheetDialogFragment() { BottomSheetDialogFragment() {
private var _binding: VB? = null private var _binding: VB? = null
/** override fun onCreateDialog(savedInstanceState: Bundle?): BottomSheetDialog =
* Configure the [AlertDialog.Builder] during [onCreateDialog]. RealAnimationBottomSheetDialog(requireContext(), theme)
*
* @param builder The [AlertDialog.Builder] to configure.
* @see onCreateDialog
*/
protected open fun onConfigDialog(builder: AlertDialog.Builder) {}
/** /**
* Inflate the [ViewBinding] during [onCreateView]. * Inflate the [ViewBinding] during [onCreateView].
@ -108,4 +106,33 @@ abstract class ViewBindingBottomSheetDialogFragment<VB : ViewBinding> :
_binding = null _binding = null
logD("Fragment destroyed") logD("Fragment destroyed")
} }
private inner class RealAnimationBottomSheetDialog
@JvmOverloads
constructor(context: Context, @StyleRes theme: Int = 0) : BottomSheetDialog(context, theme) {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// The dialog already supplies an implementation for dismissing with the normal
// bottom sheet sliding, which is odd. It works well save the scrim not actually
// activating until the sheet is out of view, but that is tolerated for now.
// TODO: Replace with custom impl that runs the scrim animation and bottom sheet
// animation in parallel. Might just switch back to the stock animation if I can
// eliminate the opacity.
dismissWithAnimation = true
}
override fun onStart() {
super.onStart()
// We have to manually trigger a hidden -> expanded transition when the dialog
// is initially opened. Hence, we set the state to hidden now and then as soon
// as we're drawing updating it to expanded.
behavior.state = BottomSheetBehavior.STATE_HIDDEN
requireView().post { behavior.state = BottomSheetBehavior.STATE_EXPANDED }
}
override fun dismiss() {
super.dismiss()
behavior.state = BottomSheetBehavior.STATE_HIDDEN
}
}
} }

View file

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (C) 2018 The Android Open Source Project
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="@integer/m3_sys_motion_duration_medium4"
android:interpolator="@interpolator/m3_sys_motion_easing_emphasized">
<translate
android:fromYDelta="100%p"
android:toYDelta="0"/>
</set>

View file

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:duration="@integer/m3_sys_motion_duration_medium3"
android:interpolator="@interpolator/m3_sys_motion_easing_emphasized"
android:fromYDelta="0"
android:toYDelta="100%p"/>
</set>

View file

@ -51,6 +51,12 @@
<style name="Widget.Auxio.BottomSheet.Dialog" parent="ThemeOverlay.Material3.BottomSheetDialog"> <style name="Widget.Auxio.BottomSheet.Dialog" parent="ThemeOverlay.Material3.BottomSheetDialog">
<item name="bottomSheetStyle">@style/Widget.Auxio.BottomSheet.Modal</item> <item name="bottomSheetStyle">@style/Widget.Auxio.BottomSheet.Modal</item>
<item name="android:windowAnimationStyle">@style/Animation.Auxio.BottomSheet.Dialog</item>
</style>
<style name="Animation.Auxio.BottomSheet.Dialog" parent="Animation.Material3.BottomSheetDialog">
<item name="android:windowEnterAnimation">@anim/bottom_sheet_slide_in</item>
<item name="android:windowExitAnimation">@anim/bottom_sheet_slide_out</item>
</style> </style>
<style name="Widget.Auxio.Image.Small" parent=""> <style name="Widget.Auxio.Image.Small" parent="">