这几天工作中遇到不少滑动冲突问题,记录下来,分享一下。
主要有两种情况:
-
ScrollView嵌套ListView
这种情况的应用场景不多,一般应用的话也多用于展示,重新计算下ListView的高度就ok
先上图:
顶层布局是一个ScrollView,里面包含一个Edittext,一个Listview,一个Button
正常情况下ScrollView不会拦截掉ListView的点击事件,不过当Edittext中的内容比较多,直到屏幕展示不开出现滚动条时,ScrollView就会拦截掉ListView的点击事件,使Listview没办法正常工作
这种情况下Listview的滑动事件会被拦截掉
解决方案:判断点击位置,按位置来确定谁来执行点击事件
解决滑动冲突问题一般有两种解决方式:
外部拦截法和内部拦截法
先来看外部拦截法
外部拦截也就是说从父控件中处理是否拦截点击事件
上代码
非完整代码
public class MyScrollView extends ScrollView {
private ListView mListView;
private float mLeft;
private float mRight;
private float mTop;
private float mBpttom;
private float mRawX;
private float mRawY;
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
switch (ev.getAction()){
case MotionEvent.ACTION_DOWN:
int[] location = new int[2];
mListView.getLocationInWindow(location);
mLeft = location[0];
mTop = location[1];
mRight = mLeft + getWidth();
mBpttom = mTop + getHeight();
mRawX = ev.getRawX();
mRawY = ev.getRawY();
if(mRawX>mLeft && mRawX<mRight
&& mRawY>mTop && mRawY<mBpttom){
return false;
}
return true;
case MotionEvent.ACTION_MOVE:
break;
case MotionEvent.ACTION_UP:
break;
}
return super.onInterceptTouchEvent(ev);
}
}
简单说一下,获取Listview在屏幕中的位置,判断点击的坐标是否在Listview中,如果是就直接不去拦截点击事件,让Listview处理
内部拦截法:
在内部view中通过requestDisallowInterceptTouchEvent()方法来干涉父控件是否拦截点击事件
代码逻辑一样的就不上代码了,重写Listview的onTouchEvent方法
如果点击位置在Listview内就调用requestDisallowInterceptTouchEvent(true)
-
ScrollView嵌套可以横向滑动的Webview(和Viewpager嵌套Listview)一样的
这个就比较简单了,判断滑动房间,外部拦截就重写父空间的onIntercepterTouchEvent 内部拦截就重写view空间的onTouchEvent方法,直接上代码
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
switch (ev.getAction()){
case MotionEvent.ACTION_DOWN:
mRawX = ev.getRawX();
mRawY = ev.getRawY();
break;
case MotionEvent.ACTION_MOVE:
float moveX = ev.getRawX();
float moveY = ev.getRawY();
float differX = Math.abs(moveX - mRawX);
float differY = Math.abs(moveY - mRawY);
if(differX>differY){
return false;
}else
return true;
case MotionEvent.ACTION_UP:
break;
}
return super.onInterceptTouchEvent(ev);
}
计算移动距离的绝对值,判断在哪个方向上移动距离长,然后处理事件
顺便提一下,Webview的loadData方法,系统提供的方法有时候也会出现乱码,可以这么处理
mWebView.getSettings().setDefaultTextEncodingName("UTF-8");
mWebView.loadData(mHtmlStr, "text/html; charset=UTF-8", null);