android - 在包含 CollapsingToolbarLayout 的 AppBarLayout 顶部时,MovableFloatingActionButton 不接收 onTouch
问题描述
我使用在此处找到的一些代码将 MovableFloatingActionButton(此对象扩展了 FloatingActionButton,只是使其可移动)添加到我的 MainActivity。MovableFloatingActionButton 在屏幕上移动得很好,包括 CollapsingToolbarLayout 区域,但是一旦我从屏幕上松开手指然后尝试再次移动 FloatingActionButton,AppBarLayout 开始移动(在垂直方向上)而不是在垂直方向上移动 MovableFloatingActionButton。AppBarLayout 中是否没有一些标志告诉它不要从悬停在它上面的对象接管 onTouch() 命令?
我已经使用 AppBarLayout behavior.setDragCallback 解决方法使 AppBarLayout 停止接管 onTouch 但不是最佳的,因为这会禁用 AppBarLayout 被触摸以向上和向下滚动整个视图的能力。“layout/content_main”内部只是一个带有 RecyclerView 的 LinearLayout,它在 CollapsingToolbarLayout 区域下方显示一个列表。CollapsingToolbarLayout 内部是一个由 8 个垂直堆叠的 TextView 组成的 LinearLayout。
activity_main.xml
<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:layout_width="match_parent"
android:layout_height="match_parent"
tools:ignore="HardcodedText"
tools:context=".MainActivity">
<android.support.design.widget.AppBarLayout
android:id="@+id/appBarLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/AppTheme.AppBarOverlay"
>
<!--app:layout_behavior="com.ktoonsez.golfclubtracker.FixedAppBarLayoutBehavior"
app:layout_collapseMode="parallax"-->
<android.support.design.widget.CollapsingToolbarLayout
android:id="@+id/collapsingToolbarLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:contentScrim="?attr/colorPrimary">
<!--<ImageView
android:src="@drawable/background_sky"
android:id="@+id/imageView"
android:layout_width="match_parent"
android:layout_height="156dp"
android:scaleType="centerCrop"
/>-->
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:popupTheme="@style/AppTheme.PopupOverlay"/>
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<include layout="@layout/content_main" />
<com.ktoonsez.golfclubtracker.MovableFloatingActionButton
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_margin="@dimen/fab_margin"
app:srcCompat="@android:drawable/ic_menu_mylocation" />
</android.support.design.widget.CoordinatorLayout>
我用来覆盖垂直拖动的示例
appBarLayout = findViewById(R.id.appBarLayout);
CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) appBarLayout.getLayoutParams();
params.setBehavior(new AppBarLayout.Behavior());
//params = (CoordinatorLayout.LayoutParams) appBarLayout.getLayoutParams();
AppBarLayout.Behavior behavior = (AppBarLayout.Behavior) params.getBehavior();
behavior.setDragCallback(new AppBarLayout.Behavior.DragCallback() {
@Override
public boolean canDrag(@NonNull AppBarLayout appBarLayout) {
return false; //Globals.AppBarLayoutCanDrag;
}
});
所以最后我只想能够在整个屏幕(RecyclerView 区域和 AppBarLayout 区域)周围移动我的 MovableFloatingActionButton 并且仍然能够从 AppBarLayout 滚动(该区域非常大,大约 1/3 到 1 /第 4 个屏幕取决于数据。
谢谢
解决方案
所以这是我想出的解决我的问题的方法:
创建了一个像这样扩展“AppBarLayout.Behavior”的类。关键是重写 onInterceptTouchEvent() 函数并返回 false。
public class AppBarLayoutBehavior extends AppBarLayout.Behavior {
public AppBarLayoutBehavior() {
super();
}
public AppBarLayoutBehavior(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public boolean onInterceptTouchEvent(CoordinatorLayout parent, AppBarLayout child, MotionEvent ev) {
return false;
}
}
然后在activity_main.xml 中的AppBarLayout 中添加以下行:
app:layout_behavior="com.codename.AppBarLayoutBehavior"
回顾一下,这允许 AppBarLayout 被触摸并允许其自身和屏幕的其余部分滚动,同时如果那是被触摸的 AppBarLayout 的区域,则不会接管我覆盖的 MovableFloatingActionButton 的拖动/触摸功能.
推荐阅读
- oracle - 如何改进我的程序以在后端成功运行?
- node.js - 删除行nodejs的第一个间距
- java - 如何在 Java 扫描器中使用多个分隔符?
- javascript - 如何使解构常量超出其范围?
- javascript - 使用 jQuery().serialize 将 jQuery ajax 调用转换为 vanilla JavaScript
- python - 对象没有属性“_committed”错误
- c# - 等待数据库中的值更新然后返回值
- ios - -[firtrace inittracewithname:] 中的崩溃断言失败,firtrace.m:86。NSInternalInconsistencyException',原因:'名称不能为 nil FCMSDK 更新
- python - 无法从本地访问在 minikube 上运行的烧瓶应用程序
- vue.js - 如何在 vue 中预取 axios 请求?