【问题标题】:How to smooth the movement of a list item at a specific position如何平滑列表项在特定位置的移动
【发布时间】:2020-12-21 12:27:30
【问题描述】:

我有列表视图。当项目处于某个位置时,他会改变颜色。 (见图)。在顶部(带有蓝色方块) - 这是我现在所拥有的。下来 - 我需要什么。但是在滚动时,当项目处于所需位置并改变颜色时,它不会顺利发生。该项目似乎跳到所需的位置。我怎样才能使这个过程更顺畅?谢谢。

这是我的视图类的一部分:

public class TimeView extends View {
...........................

    @Override
    public void setOnScrollChangeListener(OnScrollChangeListener l) {
    }

    AbsListView.OnScrollListener scrollListener = new AbsListView.OnScrollListener() {

        @Override
        public void onScrollStateChanged(final AbsListView view, int scrollState) {
            if (scrollState == SCROLL_STATE_IDLE) {
                View childView = view.getChildAt(0);
                int position = view.getFirstVisiblePosition();
                if (-childView.getTop() > childView.getHeight() / 2) {
                    position++;
                }
             
              view.setSelection(position);
               }
        }

        @Override
        public void onScroll(final AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
            for (int i = 0; i < view.getChildCount(); i++) {
                View childView = view.getChildAt(i);
                if (i == 1) {
                    childView.setBackgroundResource(R.drawable.selected_color);

                } else {
                    childView.setBackgroundResource(R.drawable.no_select_color);
                }
            }
        }

    };

【问题讨论】:

    标签: android scroll android-listview smooth-scrolling


    【解决方案1】:

    试试这个:

        @Override
        public void onScrollStateChanged(final AbsListView view, int scrollState) {
            if (scrollState == SCROLL_STATE_IDLE) {
                View firstView = view.getChildAt(0);
                Rect rect = new Rect(0, 0, firstView.getWidth(), firstView.getHeight());
                view.getChildVisibleRect(firstView, rect, null);
                int position = view.getFirstVisiblePosition();
                if (rect.height() < (firstView.getHeight() / 2)) {
                    position++;
                }
                final int finalPosition = position;
                view.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        view.smoothScrollToPositionFromTop(finalPosition, 0, 500);
                    }
                }, 1);
            }
        }
    

    更新: 上面的代码有一个恒定的建立时间(500ms)。下面的代码具有恒定的捕捉速度(0.2 像素/毫秒,这意味着向上/向下滚动一个像素需要 5 毫秒)。

        final static int SCROLL_TIME_PER_PIXEL = 5; // Time(ms) to snap a pixel.
        @Override
        public void onScrollStateChanged(final AbsListView view, int scrollState) {
            if (scrollState == SCROLL_STATE_IDLE) {
                View firstView = view.getChildAt(0);
                Rect rect = new Rect(0, 0, firstView.getWidth(), firstView.getHeight());
                view.getChildVisibleRect(firstView, rect, null);
                int position = view.getFirstVisiblePosition();
                int offset = rect.height();
                if (rect.height() < (firstView.getHeight() / 2)) {
                    position++;
                } else offset = firstView.getHeight() - rect.height();
                final int finalPosition = position; // Snap to position.
                final int finalOffset = offset; // Snap distance in pixels.
                view.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        view.smoothScrollToPositionFromTop(finalPosition, 0, finalOffset * SCROLL_TIME_PER_PIXEL);
                    }
                }, 1);
            }
        }
    

    【讨论】:

    • #i_A_mok,你能解释一下这种方法是如何工作的吗?谢谢
    • i_A_mok,谢谢。我会尝试报告结果
    • 我尝试使用您的建议,它似乎可以满足我的需要。非常感谢!
    【解决方案2】:

    如果您切换到使用 RecyclerView 而不是 ListView(无论如何您都应该这样做),您可以为此使用 SnapHelper

    SnapHelper helper = new LinearSnapHelper();
    helper.attachToRecyclerView(recyclerView);
    

    https://youtu.be/MBCuvneFEp0?t=1191

    【讨论】:

    • #Gavin Wright,谢谢您的建议。但我必须使用 ListView(
    猜你喜欢
    • 2014-11-17
    • 2011-02-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-29
    • 2023-02-25
    • 1970-01-01
    • 2015-01-12
    相关资源
    最近更新 更多