Skip to content
This repository was archived by the owner on Nov 21, 2024. It is now read-only.

Commit 82679e5

Browse files
committed
Fix BottomNavigationDrawerCallback jumping slideOffset on first open.
- Added method to calculate the bottomsheet offset when half expanded before being able to receive it in onStateChanged - Update to use MDC's addBottomSheetCallback method Change-Id: I8463b5e42901900aae908474e3d56660c57a85ba
1 parent c3bc0bd commit 82679e5

File tree

4 files changed

+41
-7
lines changed

4 files changed

+41
-7
lines changed

app/src/main/java/com/materialstudies/reply/ui/nav/BottomNavDrawerFragment.kt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ import android.view.LayoutInflater
2323
import android.view.View
2424
import android.view.ViewGroup
2525
import android.widget.FrameLayout
26-
import androidx.appcompat.content.res.AppCompatResources
2726
import androidx.fragment.app.Fragment
2827
import androidx.lifecycle.observe
2928
import com.google.android.material.bottomsheet.BottomSheetBehavior
@@ -194,7 +193,7 @@ class BottomNavDrawerFragment :
194193

195194
profileImageView.setOnClickListener { toggleSandwich() }
196195

197-
behavior.setBottomSheetCallback(bottomSheetCallback)
196+
behavior.addBottomSheetCallback(bottomSheetCallback)
198197
behavior.state = STATE_HIDDEN
199198

200199
val adapter = NavigationAdapter(this@BottomNavDrawerFragment)

app/src/main/java/com/materialstudies/reply/ui/nav/BottomNavigationDrawerCallback.kt

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,12 @@
1717
package com.materialstudies.reply.ui.nav
1818

1919
import android.view.View
20+
import androidx.coordinatorlayout.widget.CoordinatorLayout
21+
import androidx.core.view.doOnNextLayout
22+
import com.google.android.material.R
2023
import com.google.android.material.bottomsheet.BottomSheetBehavior
2124
import com.materialstudies.reply.util.normalize
25+
import kotlin.math.max
2226

2327
/**
2428
* A [BottomSheetBehavior.BottomSheetCallback] which helps break apart clients who would like to
@@ -30,17 +34,19 @@ import com.materialstudies.reply.util.normalize
3034
* in [onSlide] is corrected to guarantee that the offset 0.0 <i>always</i> be exactly at the
3135
* [BottomSheetBehavior.STATE_HALF_EXPANDED] state.
3236
*/
33-
class BottomNavigationDrawerCallback : BottomSheetBehavior.BottomSheetCallback() {
37+
class BottomNavigationDrawerCallback() : BottomSheetBehavior.BottomSheetCallback() {
3438

3539
private val onSlideActions: MutableList<OnSlideAction> = mutableListOf()
3640
private val onStateChangedActions: MutableList<OnStateChangedAction> = mutableListOf()
3741

3842
private var lastSlideOffset = -1.0F
39-
private var halfExpandedSlideOffset = 0.0F
43+
private var halfExpandedSlideOffset = Float.MAX_VALUE
4044

4145
override fun onSlide(sheet: View, slideOffset: Float) {
42-
lastSlideOffset = slideOffset
46+
if (halfExpandedSlideOffset == Float.MAX_VALUE)
47+
calculateInitialHalfExpandedSlideOffset(sheet)
4348

49+
lastSlideOffset = slideOffset
4450
// Correct for the fact that the slideOffset is not zero when half expanded
4551
val trueOffset = if (slideOffset <= halfExpandedSlideOffset) {
4652
slideOffset.normalize(-1F, halfExpandedSlideOffset, -1F, 0F)
@@ -60,6 +66,37 @@ class BottomNavigationDrawerCallback : BottomSheetBehavior.BottomSheetCallback()
6066
onStateChangedActions.forEach { it.onStateChanged(sheet, newState) }
6167
}
6268

69+
/**
70+
* Calculate the onSlideOffset which will be given when the bottom sheet is in the
71+
* [BottomSheetBehavior.STATE_HALF_EXPANDED] state.
72+
*
73+
* Recording the correct slide offset for the half expanded state happens in [onStateChanged].
74+
* Since the first time the sheet is opened, we haven't yet received a call to [onStateChanged],
75+
* this method is used to calculate the initial value manually so we can smoothly normalize
76+
* slideOffset values received between -1 and 1.
77+
*
78+
* See:
79+
* [BottomSheetBehavior.calculateCollapsedOffset]
80+
* [BottomSheetBehavior.calculateHalfExpandedOffset]
81+
* [BottomSheetBehavior.dispatchOnSlide]
82+
*/
83+
private fun calculateInitialHalfExpandedSlideOffset(sheet: View) {
84+
val parent = sheet.parent as CoordinatorLayout
85+
val behavior = BottomSheetBehavior.from(sheet)
86+
87+
val halfExpandedOffset = parent.height * (1 - behavior.halfExpandedRatio)
88+
val peekHeightMin = parent.resources.getDimensionPixelSize(
89+
R.dimen.design_bottom_sheet_peek_height_min
90+
)
91+
val peek = max(peekHeightMin, parent.height - parent.width * 9 / 16)
92+
val collapsedOffset = max(
93+
parent.height - peek,
94+
max(0, parent.height - sheet.height)
95+
)
96+
halfExpandedSlideOffset =
97+
(collapsedOffset - halfExpandedOffset) / (parent.height - collapsedOffset)
98+
}
99+
63100
fun addOnSlideAction(action: OnSlideAction): Boolean {
64101
return onSlideActions.add(action)
65102
}

app/src/main/java/com/materialstudies/reply/ui/nav/OnSlideAction.kt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,6 @@ interface OnSlideAction {
4545
toInclusive = true
4646
) slideOffset: Float
4747
)
48-
4948
}
5049

5150
/**

app/src/main/res/layout/fragment_bottom_nav_drawer.xml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,6 @@
4343
app:behavior_skipCollapsed="true"
4444
app:behavior_halfExpandedRatio="0.6">
4545

46-
4746
<androidx.recyclerview.widget.RecyclerView
4847
android:id="@+id/account_recycler_view"
4948
android:layout_width="match_parent"

0 commit comments

Comments
 (0)