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