使用说明
通过手指触摸控件位置来判断是否需要拦截该滑动事件,目前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;
}
}
}
}