pyu*_*s13 5 android android-coordinatorlayout bottom-sheet android-jetpack
我有一个带有子 NestedScrollView 的底部工作表。我想将整个 NestedScrollView 一直滚动到底部,而无需将底部工作表向上滑动。
如果用户希望底部工作表一直向上,他们必须使用锚点,别无他法。
现在,当使用开始向下滚动时,在滚动整个内容后,我希望底部工作表在下一个滚动操作时隐藏。
由于默认的底部工作表行为不允许我创建自己的自定义行为并覆盖 onNestedScroll() 和 onNestedPreScroll()。
我面临两个问题:
1 :Nestedscrollview 部分滚动并停止,因为对于底部工作表,它看到没有更多内容可以滚动。我必须向上滑动工作表才能看到其余的内容。意味着我无法在不展开工作表的情况下看到 NestedScrollView 中的最后一项。
2:如何检测 NestedScrollChild 是向上滚动还是向下滚动。因为我希望 BottomSheet 在滚动视图完成滚动其内容后拦截事件。我试过 onNestedPreScroll 但似乎不一定每次滚动孩子时都会触发它。将侦听器附加到滚动视图是唯一的解决方案吗?
在 GIF https://photos.app.goo.gl/RPmDFEtR9TbGHrau6 中查看问题的链接
下面是我的布局和行为类。
<?xml version="1.0" encoding="utf-8"?>
Run Code Online (Sandbox Code Playgroud)
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/appBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/ThemeOverlay.AppCompat.ActionBar">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
/>
</com.google.android.material.appbar.AppBarLayout>
Run Code Online (Sandbox Code Playgroud)
-->
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/bs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/bottom_sheet_background_shaded"
android:elevation="10dp"
app:behavior_hideable="false"
app:behavior_peekHeight="35dp"
app:behavior_fitToContents="false"
app:layout_behavior="com.pyus13.bottomsheetsample.MyBottomSheetBehaviour">
<ImageView
android:id="@+id/anchor"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="1dp"
android:src="@drawable/bottom_sheet_anchor_holder"
app:layout_constraintBottom_toTopOf="@+id/main_container"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<androidx.core.widget.NestedScrollView
android:id="@+id/main_container"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="15dp"
android:clipToPadding="false"
android:elevation="5dp"
android:gravity="center"
android:paddingTop="20dp"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/anchor">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<Button
android:id="@+id/change_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="Title 1"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="Title 2"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="Page 3"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="Page 4"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="Page 5"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="Change Title"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="Change Title"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="Change Title"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="Change Title"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="Change Title"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="Change Title"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="Change Title"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="Change Title"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="Change Title"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="Change Title"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="Change Title"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="Change Title"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="Change Title"/>
</LinearLayout>
</androidx.core.widget.NestedScrollView>
</androidx.constraintlayout.widget.ConstraintLayout>
Run Code Online (Sandbox Code Playgroud)
我的行为类:
class MyBottomSheetBehaviour<V : View> @JvmOverloads constructor(
context: Context? = null, attrs: AttributeSet? = null) : BottomSheetBehavior<V>(context, attrs) {
private var isScrollingDown = false
override fun onInterceptTouchEvent(parent: CoordinatorLayout, child: V, event: MotionEvent): Boolean {
if (state == STATE_COLLAPSED || state == STATE_HALF_EXPANDED) {
return false
}
return super.onInterceptTouchEvent(parent, child, event)
}
override fun onStartNestedScroll(coordinatorLayout: CoordinatorLayout, child: V, directTargetChild: View, target: View, axes: Int, type: Int): Boolean {
Log.d("Scroll", "OnNestedScroll EVent $child $target $axes $type")
if (state == STATE_COLLAPSED || state == STATE_HALF_EXPANDED) {
if (target.canScrollVertically(1) || target.canScrollVertically(-1)) {
return false
}
}
return super.onStartNestedScroll(coordinatorLayout, child, directTargetChild, target, axes, type)
}
override fun onNestedPreScroll(coordinatorLayout: CoordinatorLayout, child: V, target: View, dx: Int, dy: Int, consumed: IntArray, type: Int) {
isScrollingDown = dy > 0
super.onNestedPreScroll(coordinatorLayout, child, target, dx, dy, consumed, type)
}
Run Code Online (Sandbox Code Playgroud)
}
如果有人可以提供帮助,我想要这样的行为将不胜感激。
不过,我遇到了几乎相同的问题,布局有点不同,并且行为根本不拦截嵌套滚动。既然还没有答案,我认为值得在这里分享我的经验。
所以,我的布局如下:
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
...
<LinearLayout
android:id="@+id/bottomSheetLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:backgroundTint="@color/colorPrimary"
android:orientation="vertical"
app:layout_behavior=".view.FullNestedScrollBottomSheetBehavior"
app:behavior_hideable="false"
app:behavior_peekHeight="@dimen/bottom_sheet_min_height"
>
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/anchorImage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="-4dp"
android:layout_gravity="center"
android:paddingTop="4dp"
android:src="@drawable/ic_baseline"
android:tint="@android:color/white"
/>
<com.google.android.material.tabs.TabLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/tabLayout"
app:tabTextColor="#b2ffffff"
app:tabIconTint="@color/selector_status_tab"
app:tabRippleColor="#42ffffff"
app:tabSelectedTextColor="@android:color/white"
app:tabIndicatorColor="@android:color/white"
>
...
</com.google.android.material.tabs.TabLayout>
<androidx.viewpager.widget.ViewPager
android:id="@+id/viewPager"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@android:color/white"
/>
</LinearLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
Run Code Online (Sandbox Code Playgroud)
我最终采用了以下方法:
BottomSheet接受嵌套滚动:class FullNestedScrollBottomSheetBehavior<V: View>(
context: Context,
attrs: AttributeSet?
): BottomSheetBehavior<V>(context, attrs) {
override fun onStartNestedScroll(...) = false
}
Run Code Online (Sandbox Code Playgroud)
ViewPager包含NestedScrollView和 的a ) :RecyclerViewBottomSheetoverride fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
bottomSheetBehavior.addBottomSheetCallback(object : BottomSheetBehavior.BottomSheetCallback() {
override fun onStateChanged(bottomSheet: View, newState: Int) {}
override fun onSlide(bottomSheet: View, slideOffset: Float) {
val height = view.height - bottomSheet.top - anchorImage.height + 4.dp - tabLayout.height
val params = LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, height)
viewPager.layoutParams = params
}
})
}
Run Code Online (Sandbox Code Playgroud)
onSlide()在您拖动 之前不会调用BottomSheet,因此上述逻辑应复制为以下内容onViewCreated():override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
view.post {
val h = view.height - bottomSheetLayout.top - anchorImage.height + 4.dp - tabLayout.height
val p = LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, h)
viewPager.layoutParams = p
}
// here goes the code from the second point
}
Run Code Online (Sandbox Code Playgroud)
我认为提供的解决方案可能是实现问题中所需的确切行为的一个很好的提示。
| 归档时间: |
|
| 查看次数: |
1415 次 |
| 最近记录: |