Far*_*sbi 7 android android-layout android-coordinatorlayout android-nestedscrollview bottom-sheet
我有一个CoordinatorLayout包含两个NestedScrollViews,一个有ScrollingViewBehavior,另一个有BottomSheetBehavior和扮演BottomSheet角色,问题是当我拖动时BottomSheet,第一个NestedScrollView滚动:
我的期望:
当我滚动时BottomSheet,另一个NestedScrollView不应该滚动
我试了一下:
我创建了一个自定义的行为和覆盖onInterceptTouchEvent,在事件属于BottomSheet返回true和调用dispatchTouchEvent上BottomSheet,该功能可以防止NestedScrollView滚动,但BottomSheet不能滚动本身并单击事件BottomSheet孩子没有工作了.
这是我的布局:
<android.support.design.widget.CoordinatorLayout
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:id="@+id/main_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:animateLayoutChanges="true"
tools:ignore="UnusedAttribute">
<include
layout="@layout/toolbar"/>
<android.support.v4.widget.NestedScrollView
android:id="@+id/nested"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="?actionBarSize"
android:background="#ff0"
android:fillViewport="true"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<LinearLayout
android:id="@+id/ll1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingTop="24dp">
<Button
android:id="@+id/button_1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:background="@android:color/holo_green_dark"
android:padding="16dp"
android:text="Button 1"
android:textColor="@android:color/white"/>
<Button
android:id="@+id/button_2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:background="@android:color/holo_blue_light"
android:padding="16dp"
android:text="Button 2"
android:textColor="@android:color/white"/>
<Button
android:id="@+id/button_3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:background="@android:color/holo_red_dark"
android:padding="16dp"
android:text="Button 3"
android:textColor="@android:color/white"/>
<android.support.v4.widget.Space
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Bottom..."/>
</LinearLayout>
</android.support.v4.widget.NestedScrollView>
<android.support.v4.widget.NestedScrollView
android:id="@+id/bottom_sheet"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/holo_orange_light"
android:clipToPadding="false"
android:elevation="4dp"
android:fillViewport="true"
app:behavior_peekHeight="60dp"
app:layout_behavior=".Behavior">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/tv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clickable="true"
android:elevation="6dp"
android:focusable="true"
android:padding="16dp"
android:text="@string/ipsum"
android:textSize="16sp"/>
<RecyclerView.../>
</LinearLayout>
</android.support.v4.widget.NestedScrollView>
Run Code Online (Sandbox Code Playgroud)
和我的toolbar.xml:
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.AppBarLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="320dp"
android:fitsSystemWindows="true">
<android.support.design.widget.CollapsingToolbarLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
app:layout_scrollFlags="scroll|exitUntilCollapsed">
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="fitXY"
android:src="@drawable/lily_lake"
app:layout_collapseMode="parallax"/>
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?actionBarSize"
android:layout_gravity="bottom"
app:layout_collapseMode="pin"/>
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
Run Code Online (Sandbox Code Playgroud)
更新了更简单的解决方案.
您的问题的解决方案可分为两个部分:
要在不影响appbar的情况下提升底部工作表,我们需要检测底部工作表何时负责滚动并让appbar拒绝嵌套滚动,以便它不会接收后续嵌套滚动事件.这是通过以下onStartNestedScroll方法实现的AppBarLayout.Behavior.(见MyAppBarBehavior下面的代码.)
我们现在可以像一个独立的滑动面板一样向上拖动底部工作表.
现在我们已经拖了底板,我们可以把它拖回来吗?是的,不.如果底部工作表滚动到其内容的顶部,那么如果我们触摸appbar 下方的底部工作表,我们可以向下拖动底部工作表.如果我们触摸appbar上的底部纸张(当然,它位于底部纸张后面),那么我们就无法将底部纸张向下拖动.未经我们修改,此问题存在于基础代码中.我认为底页覆盖appbar是不寻常的.
为了演示此通知,在此视频中,当拖动底部工作表时,appbar会在底部工作表后面打开.
要改变这种行为,我们将覆盖onInterceptTouchEvent的AppBarLayout.Behavior,如果底片被触摸返回false.
这是新的AppBarLayout.Behavior:
MyAppBarBehavior
class MyAppBarBehavior extends AppBarLayout.Behavior {
private boolean mIsSheetTouched = false;
@Override
public boolean onStartNestedScroll(CoordinatorLayout coordinatorLayout, AppBarLayout child,
View directTargetChild, View target, int axes, int type) {
// Set flag if the bottom sheet is responsible for the nested scroll.
mIsSheetTouched = target.getId() == R.id.bottom_sheet;
// Only consider starting a nested scroll if the bottom sheet is not touched; otherwise,
// we will let the other views do the scrolling.
return !mIsSheetTouched
&& super.onStartNestedScroll(coordinatorLayout, child, directTargetChild,
target, axes, type);
}
@Override
public boolean onInterceptTouchEvent(CoordinatorLayout parent, AppBarLayout child, MotionEvent ev) {
// Don't accept touch stream here if the bottom sheet is touched. This will permit the
// bottom sheet to be dragged down without interaction with the appBar. Reset on cancel.
if (ev.getActionMasked() == MotionEvent.ACTION_CANCEL) {
mIsSheetTouched = false;
}
return !mIsSheetTouched && super.onInterceptTouchEvent(parent, child, ev);
}
}
Run Code Online (Sandbox Code Playgroud)
(我不应该用特定的方法确定底页id,但这只是一个演示.)
将自定义行为添加到appbar:
<android.support.design.widget.AppBarLayout
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="320dp"
android:fitsSystemWindows="true"
app:layout_behavior=".MyAppBarBehavior"
app:expanded="true">
Run Code Online (Sandbox Code Playgroud)
这是最终结果:
可能还有其他方法可以实现这一目标.我可能会使用现有的滑动面板库(如AndroidSlidingUpPanel),而不是将底部工作表放在嵌套的滚动环境中,然后我们必须撤消环境的影响.
| 归档时间: |
|
| 查看次数: |
2489 次 |
| 最近记录: |