天天看點

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;
    }
}
           

繼續閱讀