📜  listView 禁用拉动飞溅 (1)

📅  最后修改于: 2023-12-03 15:32:43.551000             🧑  作者: Mango

禁用ListView拉动飞溅

当我们在开发应用时会使用到ListView来展示数据,但是在默认情况下,当ListView滚动到顶部或底部时会出现拉动飞溅的效果,这不仅影响用户体验,还会影响应用整体的美观度。因此,我们需要禁用ListView的拉动飞溅。下面将介绍具体的实现方法。

方法一:使用第三方库

推荐使用Android Support Library中的RecyclerView代替ListView。RecyclerView是一个功能更为强大的控件,同时也默认提供了禁用拉动飞溅的功能。如果要使用ListView,可以使用第三方库Android-ObservableScrollView来禁用拉动飞溅。Android-ObservableScrollView是一个可观察的滚动视图库,它提供了多种观察ListView滚动事件的方法,其中包括禁用拉动飞溅的方法。

ObservableListView listView = findViewById(R.id.list_view);
listView.setScrollViewCallbacks(new ObservableScrollViewCallbacks() {
    @Override
    public void onScrollChanged(int scrollY, boolean firstScroll, boolean dragging) {
        // 滚动回调
    }
  
    @Override
    public void onDownMotionEvent() {
        // 手指按下回调
    }
  
    @Override
    public void onStopNestedScroll() {
        // 停止滚动回调
    }
  
    @Override
    public void onUpOrCancelMotionEvent(ScrollState scrollState) {
        // 手指抬起或取消回调
    }
  
    @Override
    public void onScrollStateChanged(int state) {
        // 滚动状态改变回调
    }
});
方法二:使用自定义ListView

另外一种方法是继承ListView,并重写onTouchEvent方法,在该方法中计算ListView滚动的距离,当滚动到顶部或底部时,将事件拦截,从而禁用拉动飞溅效果。

public class CustomListView extends ListView {
    private float mDownY;
    private float mMoveY;
    private float mLastY;
    private int mMaxOverScrollY;
  
    public CustomListView(Context context) {
        super(context);
        initView();
    }
  
    public CustomListView(Context context, AttributeSet attrs) {
        super(context, attrs);
        initView();
    }
  
    public CustomListView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initView();
    }
  
    @SuppressLint("ClickableViewAccessibility")
    private void initView() {
        mMaxOverScrollY = getContext().getResources().getDimensionPixelSize(R.dimen.listview_overscroll_distance);
        setOverScrollMode(OVER_SCROLL_NEVER); // 禁用ListView的拉动飞溅效果
        setVerticalScrollBarEnabled(false); // 禁用ListView的垂直滚动条
        setOnTouchListener(new OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                switch (event.getAction()) {
                    case MotionEvent.ACTION_DOWN:
                        mDownY = event.getRawY();
                        mLastY = mDownY;
                        break;
                    case MotionEvent.ACTION_MOVE:
                        mMoveY = event.getRawY();
                        if (mMoveY - mLastY < 0 && getLastVisiblePosition() == getCount() - 1 && Math.abs(mMoveY - mDownY) >= mMaxOverScrollY) {
                            // 拉动到底部
                            return true; // 拦截事件
                        } else if (mMoveY - mLastY > 0 && getFirstVisiblePosition() == 0 && Math.abs(mMoveY - mDownY) >= mMaxOverScrollY) {
                            // 拉动到顶部
                            return true; // 拦截事件
                        }
                        mLastY = mMoveY;
                        break;
                    default:
                        break;
                }
                return false;
            }
        });
    }
}

用以上两种方法都可以禁用ListView的拉动飞溅效果,开发者可以根据实际情况进行选择。