天天看点

Listview嵌套Gallery滑动冲突问题解决

普通的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;
    }
}
           

继续阅读