NestedScrollView平滑滚动至顶部及指定视图问题(API 27、Support 27.0.2)
NestedScrollView滚动问题解决方案
我之前也碰到过类似的NestedScrollView滚动问题,结合你使用的API27和Support库27.0.2的特性,给你针对性的解决思路:
问题1:调用smoothScrollTo(0, 0)无法平滑滚动至顶部,仅轻微跳动
这种情况大概率是NestedScrollView和父布局(比如CoordinatorLayout)或者内部滑动组件的滚动状态冲突了,导致平滑滚动被中断。试试下面这几种方法:
先停止嵌套滚动再执行平滑滚动:
在调用smoothScrollTo之前,先调用stopNestedScroll()终止可能正在进行的嵌套滚动操作,确保平滑滚动能正常触发:nestedScrollView.stopNestedScroll(); nestedScrollView.smoothScrollTo(0, 0);使用postDelayed延迟执行:
如果是视图还没完全布局完成导致的滚动异常,可以延迟一小段时间(比如100ms)再执行滚动,让视图状态稳定下来:nestedScrollView.postDelayed(() -> { nestedScrollView.smoothScrollTo(0, 0); }, 100);检查是否有AppBarLayout影响:
如果布局里包含AppBarLayout,可能需要先让它完全展开再滚动NestedScrollView:AppBarLayout appBarLayout = findViewById(R.id.app_bar); appBarLayout.setExpanded(true, true); nestedScrollView.smoothScrollTo(0, 0);
问题2:平滑滚动至内部指定视图
要滚动到NestedScrollView里的某个子视图,核心是获取该视图相对于NestedScrollView的顶部坐标,再调用平滑滚动方法。注意必须等视图完成布局后再获取坐标,否则会得到错误数值:
基础实现方法:
View targetView = findViewById(R.id.your_target_view); nestedScrollView.post(() -> { // 获取目标视图相对于NestedScrollView的顶部位置 int targetTop = targetView.getTop(); // 执行平滑滚动 nestedScrollView.smoothScrollTo(0, targetTop); });考虑NestedScrollView的padding:
如果NestedScrollView设置了顶部padding,需要把padding值加上,确保滚动位置准确:int paddingTop = nestedScrollView.getPaddingTop(); int targetTop = targetView.getTop() + paddingTop; nestedScrollView.smoothScrollTo(0, targetTop);监听视图布局完成(更稳妥的方式):
如果视图是动态添加的或布局加载较慢,可以用ViewTreeObserver监听布局完成事件:View targetView = findViewById(R.id.your_target_view); targetView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { @Override public void onGlobalLayout() { // 移除监听避免重复触发 targetView.getViewTreeObserver().removeOnGlobalLayoutListener(this); int targetTop = targetView.getTop(); nestedScrollView.smoothScrollTo(0, targetTop); } });
内容的提问来源于stack exchange,提问作者Konstantin Konopko
相关产品推荐
相关产品推荐

