ScrollView巢狀ViewPager引起的滑動衝突的解決方案
導讀:ScrollView巢狀ViewPager引起的滑動衝突,原因是S從rollView和ViewPager都有滑動的效果,當我們發生滑動這個動作時,系統不知道 要交給那個控制元件來處理滑動操作,故出現了衝突。
知道了原理,我們要做的就是
1.給最先捕獲事件的View一些引數,讓其根據引數做比較,然後判斷出Motion到底要交給誰來處理。關鍵點:判斷x方向與y方向移動距離大小的比較,從而判斷是ViewPager還是ScrollView的滑動。
或者
2.我們直接手動操作程式碼告訴讓哪個控制元件來處理Motion
因此解決方案會有兩種,下面就讓我們一起來看看吧~~~~~~~~
方案一:
自定義ViewPager作為子控制元件
public class ChildViewPager extends ViewPager{
/** 觸控時按下的點 **/
PointF downP = new PointF();
/** 觸控時當前的點 **/
PointF curP = new PointF();
OnSingleTouchListener onSingleTouchListener;
public ChildViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
}
public ChildViewPager(Context context) {
super(context);
// TODO Auto-generated constructor stub
}
@Override
public boolean onInterceptTouchEvent(MotionEvent arg0) {
// TODO Auto-generated method stub
//當攔截觸控事件到達此位置的時候,返回true,
//說明將onTouch攔截在此控制元件,進而執行此控制元件的onTouchEvent
return true;
}
@Override
public boolean onTouchEvent(MotionEvent arg0) {
// TODO Auto-generated method stub
//每次進行onTouch事件都記錄當前的按下的座標
curP.x = arg0.getX();
curP.y = arg0.getY();
if(arg0.getAction() == MotionEvent.ACTION_DOWN){
//記錄按下時候的座標
//切記不可用 downP = curP ,這樣在改變curP的時候,downP也會改變
downP.x = arg0.getX();
downP.y = arg0.getY();
//此句程式碼是為了通知他的父ViewPager現在進行的是本控制元件的操作,不要對我的操作進行干擾
getParent().requestDisallowInterceptTouchEvent(true);
}
if(arg0.getAction() == MotionEvent.ACTION_MOVE){
//此句程式碼是為了通知他的父ViewPager現在進行的是本控制元件的操作,不要對我的操作進行干擾
getParent().requestDisallowInterceptTouchEvent(true);
}
if(arg0.getAction() == MotionEvent.ACTION_UP){
//在up時判斷是否按下和鬆手的座標為一個點
//如果是一個點,將執行點選事件,這是我自己寫的點選事件,而不是onclick
if(downP.x==curP.x && downP.y==curP.y){
onSingleTouch();
return true;
}
}
return super.onTouchEvent(arg0);
}
/**
* 單擊
*/
public void onSingleTouch() {
if (onSingleTouchListener!= null) {
onSingleTouchListener.onSingleTouch();
}
}
/**
* 建立點選事件介面
* @author wanpg
*
*/
public interface OnSingleTouchListener {
public void onSingleTouch();
}
public void setOnSingleTouchListener(OnSingleTouchListener onSingleTouchListener) {
this.onSingleTouchListener = onSingleTouchListener;
}
}
方案二:
/*** 能夠相容ViewPager的ScrollView
* @Description: 解決了ViewPager在ScrollView中的滑動反彈問題
* @File: ScrollViewExtend.java
* @Package com.image.indicator.control
* @Author Hanyonglu
* @Date 2012-6-18 下午01:34:50
* @Version V1.0
*/
public class ScrollViewExtend extends ScrollView {
// 滑動距離及座標
private float xDistance, yDistance, xLast, yLast;
public ScrollViewExtend(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
xDistance = yDistance = 0f;
xLast = ev.getX();
yLast = ev.getY();
break;
case MotionEvent.ACTION_MOVE:
final float curX = ev.getX();
final float curY = ev.getY();
xDistance += Math.abs(curX - xLast);
yDistance += Math.abs(curY - yLast);
xLast = curX;
yLast = curY;
if(xDistance > yDistance){
return false;
}
}
return super.onInterceptTouchEvent(ev);
}
}