如何使列表项在特定位置的移动变得平滑

问题描述

我有listView。当物品处于特定位置时,他会更改颜色。 (参见图片)。在顶部(带有蓝色正方形)-这就是我现在所拥有的。下来-我需要的。但是在滚动时,当项目位于所需位置并更改颜色时,它不会平滑发生。该项目似乎跳到所需位置。如何使此过程更流畅?谢谢。

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

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);
                }
            }
        }

    };

解决方法

如果您改用RecyclerView而不是ListView(无论如何都应这样做),则可以使用SnapHelper

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

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

,

尝试一下:

    @Override
    public void onScrollStateChanged(final AbsListView view,int scrollState) {
        if (scrollState == SCROLL_STATE_IDLE) {
            View firstView = view.getChildAt(0);
            Rect rect = new Rect(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,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,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,finalOffset * SCROLL_TIME_PER_PIXEL);
                }
            },1);
        }
    }