smoothScrollToPositionFromTop()并不总是像它应该的那样工作

men*_*gel 22 android

我已经尝试了一段时间来使smoothScrollToPositionFromTop()工作,但它并不总是滚动到正确的位置.

我在一个布局中有一个ListView(有10个项目),旁边有10个按钮,所以我可以滚动到列表中的每个项目.通常当我向后或向前滚动一个位置时它工作正常,但是当我尝试向后或向前滚动超过3个位置时,ListView并不完全在所选位置结束.当它失败时,通常会关闭0.5到1.5个项目,当滚动失败时它不能真正预测.

在notifyDataSetChanged无法在android中工作之后我也检查了smoothScrollToPosition,但是这个修复程序对我不起作用而且我不更改任何数据.

我真的想自动滚动到选定的列表项目,但不是我无法弄清楚如何.有没有人之前有这个问题,知道如何解决它?

Lar*_*erg 50

这是一个已知的错误.请参阅https://code.google.com/p/android/issues/detail?id=36062

但是,我实现了这个解决方案,处理可能发生的所有边缘情况:

第一次调用smothScrollToPositionFromTop(position)然后,当滚动完成时,调用setSelection(position).后一个调用通过直接跳到所需位置来纠正不完整的滚动.这样做,用户仍然会将其动画滚动到此位置.

我在两个辅助方法中实现了这个解决方法:

smoothScrollToPositionFromTop()

public static void smoothScrollToPositionFromTop(final AbsListView view, final int position) {
    View child = getChildAtPosition(view, position);
    // There's no need to scroll if child is already at top or view is already scrolled to its end
    if ((child != null) && ((child.getTop() == 0) || ((child.getTop() > 0) && !view.canScrollVertically(1)))) {
        return;
    }

    view.setOnScrollListener(new AbsListView.OnScrollListener() {
        @Override
        public void onScrollStateChanged(final AbsListView view, final int scrollState) {
            if (scrollState == SCROLL_STATE_IDLE) {
                view.setOnScrollListener(null);

                // Fix for scrolling bug
                new Handler().post(new Runnable() {
                    @Override
                    public void run() {
                        view.setSelection(position);
                    }
                });
            }
        }

        @Override
        public void onScroll(final AbsListView view, final int firstVisibleItem, final int visibleItemCount,
                                 final int totalItemCount) { }
    });

    // Perform scrolling to position
    new Handler().post(new Runnable() {
        @Override
        public void run() {
            view.smoothScrollToPositionFromTop(position, 0);
        }
    });
}
Run Code Online (Sandbox Code Playgroud)

getChildAtPosition()

public static View getChildAtPosition(final AdapterView view, final int position) {
    final int index = position - view.getFirstVisiblePosition();
    if ((index >= 0) && (index < view.getChildCount())) {
        return view.getChildAt(index);
    } else {
        return null;
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 很好的解决方法!它就像一个魅力. (3认同)