这几天工作中遇到不少滑动冲突问题,记录下来,分享一下。
主要有两种情况:
- 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 && mRawXmTop && mRawY
简单说一下,获取Listview在屏幕中的位置,判断点击的坐标是否在Listview中,如果是就直接不去拦截点击事件,让Listview处理
内部拦截法:
在内部view中通过requestDisallowInterceptTouchEvent()方法来干涉父控件是否拦截点击事件
代码逻辑一样的就不上代码了,重写Listview的onTouchEvent方法
如果点击位置在Listview内就调用requestDisallowInterceptTouchEvent(true)
- ScrollView嵌套可以横向滑动的Webview(和Viewpager嵌套Listview)一样的
@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);