NestedScrollView 的 fullScroll(View.FOCUS_UP) 无法正常工作

NestedScrollView's fullScroll(View.FOCUS_UP) not working properly

我有一个填充有垂直 LinearLayout 的 NestedScrollView,它本身有一堆不同视图类型的子视图:多个 TextView、两个静态 GridView,甚至还有一个 FrameLayout 以在所有这些视图下方显示一个 Fragment。

按下后退按钮时,如果用户滚动到某个点以下,而不是完成 Activity,则调用 "scrollToTop" 方法:

public static void scrollToTop(final NestedScrollView scrollview) {
    new Handler().postDelayed(new Runnable() {
        public void run() {
            scrollview.fullScroll(NestedScrollView.FOCUS_UP);
        }
    }, 200);
}

这适用于我的应用程序的早期版本,它位于 Play 商店中。但是现在,在将我的应用程序更新为目标 Android Oreo(并将支持库更新到版本 26.0.2)之后,它似乎没有滚动到顶部,而是从 NestedScrollView 的原始滚动位置下方开始滚动,然后停止它在哪里。所以它只是看起来像一个奇怪的口吃。然而,在某些位置,它确实滚动到顶部(尽管很少且不一致),而在其他位置它实际上滚动到底部,出于什么原因我不明白。

我一直在试验视图聚焦能力,但无济于事。例如,我读到 Static GridViews 可能会在滚动时中断焦点。我也试过各种不同的方法来向上滚动,比如

scrollview.pageScroll(View.FOCUS_UP);

scrollview.smoothScrollTo(0,0);

但似乎没有任何效果。这次支持库有问题吗?

试试这个

android:descendantFocusability="blocksDescendants" 添加到 NestedScrollView 内的 LinearLayout 并且这也是

滚动到 NestedScrollView 的顶部使用这个

NestedScrollView.scrollTo(0, 0);

编辑

fling() and smoothScrollTo

nestedScrollView.post(new Runnable() {
   @Override
   public void run() {
      nestedScrollView.fling(0);
      nestedScrollView.smoothScrollTo(0, 0);
   }
});

更新:

找到更好的解决方案。试试这个组合:

scrollView.fling(0);  // Sets mLastScrollerY for next command
scrollView.smoothScrollTo(0, 0);  // Starts a scroll itself

看起来像 hack,但在我的两台设备上都运行良好(使用支持库 26.0.0 和 27.0.2 测试)。可用于平滑滚动到任何其他位置。根据思路认为问题出在missing update of mLastScrollerY.

如果它对你有用,请留下反馈。

原回答:

也遇到这个问题

NestedScrollView.smoothScrollTo(0, 0) 在支持库中工作到 25.4.0,从 26.0.0 到当前的 27.0.2 不工作。 NestedScrollView的内容无所谓(一些TextView就够了)。

这个错误已经 reported twice on Google Issue Tracker. Minimal project to reproduce it can be found on GitHub

找到两个可行的解决方案:

  1. NestedScrollView.scrollTo(0, 0)(看到接受的答案,突然跳转)
  2. NestedScrollView.fling(-10000)(滚动流畅,但适当的速度值取决于当前位置、设备、所需的滚动时间等)

在我的案例中没有必要改变可聚焦性。

这段代码适合我。

scrollView.post {
    scrollView.fling(0)
    scrollView.fullScroll(ScrollView.FOCUS_UP)
}

它似乎终于在 28.0.0 支持库中得到修复,所以 NestedScrollView.smoothScrollTo() 对我来说是预期的