Floating Action Button(FAB)滚动显示隐藏功能失效问题求助
我来帮你排查并解决这个FAB滚动隐藏/显示失效的问题,结合你的代码来看,主要是自定义Behavior的实现细节和布局配置有问题,下面一步步给你修正:
一、修复自定义ScrollAwareFABBehavior的逻辑
你的Behavior存在几个小问题:比如没有限制垂直滚动轴、缺少滚动阈值导致频繁触发、状态判断不够严谨。这里给你一个完善后的版本:
public class ScrollAwareFABBehavior extends FloatingActionButton.Behavior { private static final String TAG = "ScrollAwareFABBehavior"; private int scrollThreshold = 10; // 设置滚动阈值,避免轻微滚动就触发动画 private int totalScrolledDistance = 0; public ScrollAwareFABBehavior(Context context, AttributeSet attrs) { super(context, attrs); } @Override public boolean onStartNestedScroll(CoordinatorLayout coordinatorLayout, FloatingActionButton child, View directTargetChild, View target, int nestedScrollAxes) { // 只监听垂直方向的滚动事件 return nestedScrollAxes == ViewCompat.SCROLL_AXIS_VERTICAL; } @Override public void onNestedScroll(CoordinatorLayout coordinatorLayout, FloatingActionButton child, View target, int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed) { super.onNestedScroll(coordinatorLayout, child, target, dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed); totalScrolledDistance += dyConsumed; // 向下滚动超过阈值且FAB可见时,隐藏它 if (totalScrolledDistance > scrollThreshold && child.getVisibility() == View.VISIBLE) { child.hide(new FloatingActionButton.OnVisibilityChangedListener() { @Override public void onHidden(FloatingActionButton fab) { super.onHidden(fab); fab.setVisibility(View.INVISIBLE); // 确保状态标记正确 } }); totalScrolledDistance = 0; // 重置滚动距离 } // 向上滚动超过阈值且FAB不可见时,显示它 else if (totalScrolledDistance < -scrollThreshold && child.getVisibility() != View.VISIBLE) { child.show(); totalScrolledDistance = 0; // 重置滚动距离 } } }
二、布局中正确配置Behavior
确保你的FAB在CoordinatorLayout内部,并且给它指定自定义Behavior属性,替换成你实际的包名:
<android.support.design.widget.FloatingActionButton android:id="@+id/floating_action_button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="bottom|end" android:layout_margin="16dp" android:src="@drawable/ic_mode_edit_black_24px" android:background="@color/colorPrimary" app:backgroundTint="@color/colorPrimary" app:fabSize="normal" app:layout_behavior="com.yourpackage.ScrollAwareFABBehavior" /> <!-- 这里添加Behavior -->
另外,别忘了检查你引入的content_scrolling布局里的RecyclerView,必须添加以下属性,让CoordinatorLayout能识别它的滚动事件:
app:layout_behavior="@string/appbar_scrolling_view_behavior"
三、移除冲突的滚动监听
如果你使用了上面的自定义Behavior,一定要移除RecyclerView的OnScrollListener,否则两个逻辑会冲突,导致FAB状态异常。如果坚持想用滚动监听的方式,也可以优化你的监听逻辑:
final FloatingActionButton mFloatingActionButton = findViewById(R.id.floating_action_button); mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { private int scrollThreshold = 10; private int totalScrolled = 0; @Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) { super.onScrolled(recyclerView, dx, dy); totalScrolled += dy; if (totalScrolled > scrollThreshold && mFloatingActionButton.isShown()) { mFloatingActionButton.hide(); totalScrolled = 0; } else if (totalScrolled < -scrollThreshold && !mFloatingActionButton.isShown()) { mFloatingActionButton.show(); totalScrolled = 0; } } });
这里用isShown()代替直接判断Visibility,能更准确地获取FAB的实际显示状态,同时添加滚动阈值避免频繁触发动画。
四、检查布局嵌套的正确性
你的布局是DrawerLayout包裹CoordinatorLayout,这个结构没问题,但要确保:
- CoordinatorLayout的
android:fitsSystemWindows="true"属性正确设置,避免布局偏移影响滚动判断 - RecyclerView所在的布局根节点没有拦截滚动事件,确保滚动能传递到CoordinatorLayout
按照上面的步骤修改后,FAB应该就能正常在向上滚动时隐藏、向下滚动时显示了。
内容的提问来源于stack exchange,提问作者Mohamed Mo'nes
相关产品推荐
相关产品推荐

