普通的Listview为纵向滑动,Gallery为横向滑动,当Listview的item包含Gallery的时候滑动就会出现冲突,导致Gallery滑动失效,解决这个问题可以通过改变Gallery的触摸事件响应逻辑来解决。
相关参数
getScaledTouchSlop():是一个距离,表示滑动的时候,手的移动要大于这个距离才开始移动控件,应该是触发移动事件的最短距离,简称触发距离。
触摸坐标:手指按下位置的坐标(x(水平方向),y(竖直方向))
水平方向滑动距离:开始触摸位置Xa到结束位置Xb两点坐标的下水平方向的距离(计算方式|Xa-Xb|)
竖直方向滑动距离:开始触摸位置Ya到结束位置Yb两点坐标的下竖直方向的距离(计算方式|Ya-Yb|)
横向滑动:水平方向滑动距离大于竖直方向距离并且水平距离大于触发距离(表明用户意图为滑动Gallery,因此此事件交给Gallery处理)
纵向滑动:水平方向距离小于竖直方向距离(表明用户意图是滑动Listview,因此此次滑动交给Listview处理)
//实现逻辑
public boolean onInterceptTouchEvent(MotionEvent ev) {
final ViewConfiguration configuration = ViewConfiguration
.get(getContext());
mTouchSlop = configuration.getScaledTouchSlop();//触摸最短距离
final int action = ev.getAction();
//x坐标
final float x = ev.getX();//每次触摸发生变化的低吼都会记录下坐标
//y坐标
final float y = ev.getY();//每次触摸发生变化的低吼都会记录下坐标
switch (action) {
case MotionEvent.ACTION_DOWN://记录初始位置
mLastMotionX = x;
mLastMotionY = y;
break;
case MotionEvent.ACTION_MOVE:
//此时的xy是手指离开时的位置坐标
final int deltaX = (int) (mLastMotionX - x);//水平方向滑动距离
final int deltaY = (int) (mLastMotionY - y);//垂直方向滑动距离
if (Math.abs(deltaX) > mTouchSlop && Math.abs(deltaY)<Math.abs(deltaX)) {//表明是横向滑动交给Gallery处理
return true;
}
break;
}
return false;
}
完整代码
自动以一个Gallery滑动的时候做监听逻辑处理。
import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.ViewConfiguration;
import android.widget.Gallery;
public class GuideGallery extends Gallery {
private float mLastMotionX;//初始x坐标
private float mLastMotionY;//初始y坐标
private int mTouchSlop;//触摸最短距离
public GuideGallery(Context context) {
super(context);
}
public GuideGallery(Context context, AttributeSet attrs) {
super(context, attrs);
}
public GuideGallery(Context context, AttributeSet attrs,
int defStyle) {
super(context, attrs, defStyle);
}
public boolean onInterceptTouchEvent(MotionEvent ev) {
final ViewConfiguration configuration = ViewConfiguration
.get(getContext());
mTouchSlop = configuration.getScaledTouchSlop();//触摸最短距离
final int action = ev.getAction();
//x坐标
final float x = ev.getX();//每次触摸发生变化的低吼都会记录下坐标
//y坐标
final float y = ev.getY();//每次触摸发生变化的低吼都会记录下坐标
switch (action) {
case MotionEvent.ACTION_DOWN://记录初始位置
mLastMotionX = x;
mLastMotionY = y;
break;
case MotionEvent.ACTION_MOVE:
//此时的xy是手指离开时的位置坐标
final int deltaX = (int) (mLastMotionX - x);//水平方向滑动距离
final int deltaY = (int) (mLastMotionY - y);//垂直方向滑动距离
if (Math.abs(deltaX) > mTouchSlop && Math.abs(deltaY) < Math.abs(deltaX)) {//表明是横向滑动交给,Gallery
return true;
}
break;
}
return false;
}
}