Scrollview嵌套listview解决滑动冲突

Scrollview嵌套listview解决滑动冲突

使用说明

通过手指触摸控件位置来判断是否需要拦截该滑动事件,目前scrollview中只能处理一个
listview或者gridview,如果scrollview中有多个只能任选其一

使用方法

只需将listview设置到scrollviewlist中即可
scrollviewlist.setListView(listview);

简单粗暴上代码

import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.AbsListView;
import android.widget.ScrollView;

/**
 * Created by MBENBEN on 2016/10/28 14 : 40.
 * scrollview嵌套listview解决冲突事件
 */

public class ListScrollView extends ScrollView implements AbsListView.OnScrollListener {

private AbsListView listView;
private int scrollState;
//第一个条目
private boolean firstVisibleItem = false;
//最后一个条目
private boolean lastVisibleItem = false;
private float downY = -1;
private float downX = -1;

public ListScrollView(Context context, AttributeSet attrs) {
    super(context, attrs);
}

public ListScrollView(Context context) {
    super(context);
}


/**
 * 覆写onInterceptTouchEvent方法,点击操作发生在ListView的区域的时候,
 * 返回false让ScrollView的onTouchEvent接收不到MotionEvent,而是把Event传到下一级的控件中
 */
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
    // TODO Auto-generated method stub
    if (listView != null && checkArea(listView, ev)) {
        switch (ev.getAction()) {
            case MotionEvent.ACTION_DOWN:
                downY = ev.getY();
                downX = ev.getX();
                break;
            case MotionEvent.ACTION_MOVE:
                if (downX == -1 || downY == -1) {
                    downY = ev.getY();
                    downX = ev.getX();
                }

                float moveY = ev.getY();
                float moveX = ev.getX();
                if (Math.abs(moveX - downX) > Math.abs(moveY - downY)) {
                    //左右滑动
                } else {
                    //上下滑动
                    if (moveY - downY > 0) {
                        //向下滑动
                        if (firstVisibleItem) {
                            //不拦截scrollview
                            if (listView != null) {
                                listView.setSelection(0);
                            }
                            return super.onInterceptTouchEvent(ev);
                        } else {
                            return false;
                        }
                    } else {
                        //向上滑动
                        if (lastVisibleItem) {
                            //不拦截scrollview
                            if (listView != null) {
                                listView.setSelection(listView.getLastVisiblePosition());
                            }
                            return super.onInterceptTouchEvent(ev);
                        } else {
                            return false;
                        }
                    }
                }
                break;
            case MotionEvent.ACTION_UP:
                downY = -1;
                downX = -1;
                break;
        }
    }
    return super.onInterceptTouchEvent(ev);
}

private void listenerListView(AbsListView listView) {
    if (listView != null) {
        listView.setOnScrollListener(this);
    }
}

/**
 * 测试view是否在点击范围内
 *
 * @param v
 * @return
 */
private boolean checkArea(View v, MotionEvent event) {
    float x = event.getRawX();
    float y = event.getRawY();
    int[] locate = new int[2];
    v.getLocationOnScreen(locate);
    int l = locate[0];
    int r = l + v.getWidth();
    int t = locate[1];
    int b = t + v.getHeight();
    if (l < x && x < r && t < y && y < b) {
        return true;
    }
    return false;
}

public AbsListView getListView() {
    return listView;
}

/**
 * 设置listview并设置监听
 *
 * @param listView
 */
public void setListView(AbsListView listView) {
    this.listView = listView;
    listenerListView(listView);
}


@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
    this.scrollState = scrollState;
}


@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
    //显示第一个条目且手指向下滑动,不需要拦截scrollview的滑动事件
    if (firstVisibleItem == 0) {
        this.firstVisibleItem = true;
    } else {
        this.firstVisibleItem = false;
    }

    if (listView.getAdapter() != null) {
        //显示最后一个条目且手指向上滑动,不需要拦截scrollview的滑动事件
        if (listView.getLastVisiblePosition() + 1 == listView.getAdapter().getCount()) {
            this.lastVisibleItem = true;
        } else {
            this.lastVisibleItem = false;
        }
    }
}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值