NestedScrollView设置滚动监听后滚动时页面闪烁问题求助
滚动显隐ActionBar闪烁问题解决方案
核心根因
当前逻辑只要检测到滚动方向变化就立刻切换控件显隐,NestedScrollView滚动过程中极易出现微小的上下位移波动(比如用户滑动操作的细微抖动、滚动惯性的边缘回弹),会频繁触发方向判断,导致显隐状态反复切换,产生闪烁。
修复方案
1. 新增滚动阈值+状态判断逻辑
只有滚动距离超过设定的阈值(推荐8~12dp,可根据业务调整),且目标状态和当前状态不一致时,才执行显隐操作,避免无意义的状态切换:
// 先定义全局变量 private int mScrollThreshold = dp2px(10); // 滚动阈值,10dp转px private int mTotalScrollDy = 0; // 累计滚动差值 private boolean mIsActionBarVisible = true; // 记录actionBar当前显隐状态 private boolean mIsSearchBarVisible = true; // 记录searchBar当前显隐状态 // dp转px工具方法 private int dp2px(float dpValue) { final float scale = getResources().getDisplayMetrics().density; return (int) (dpValue * scale + 0.5f); } scrollView.setOnScrollChangeListener(new View.OnScrollChangeListener() { @Override public void onScrollChange(View v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) { int dy = scrollY - oldScrollY; mTotalScrollDy += dy; // 向上滚动,累计差值超过阈值,且当前控件是显示状态才隐藏 if (mTotalScrollDy > mScrollThreshold) { if (searchActive) { if (mIsSearchBarVisible) { searchBar.setVisibility(View.GONE); mIsSearchBarVisible = false; } } else { if (mIsActionBarVisible) { actionBar.setVisibility(View.GONE); mIsActionBarVisible = false; } } mTotalScrollDy = 0; // 重置累计差值 } // 向下滚动,累计差值小于负阈值,且当前控件是隐藏状态才显示 else if (mTotalScrollDy < -mScrollThreshold) { if (searchActive) { if (!mIsSearchBarVisible) { searchBar.setVisibility(View.VISIBLE); mIsSearchBarVisible = true; } } else { if (!mIsActionBarVisible) { actionBar.setVisibility(View.VISIBLE); mIsActionBarVisible = true; } } mTotalScrollDy = 0; // 重置累计差值 } } });
2. 可选优化:增加过渡动画
如果想要避免显隐的生硬跳变,可以给控件添加位移动画,提升流畅度:
// 隐藏动画 private void hideView(View view) { view.animate().translationY(-view.getHeight()).setDuration(200).start(); } // 显示动画 private void showView(View view) { view.animate().translationY(0).setDuration(200).start(); }
把上述代码里的setVisibility替换成对应的动画方法即可,注意同步更新状态标记位。
内容的提问来源于stack exchange,提问作者Saurav Sharma
相关产品推荐
相关产品推荐

