1. 程式人生 > >ViewPager與百度地圖衝突的純淨解決方案

ViewPager與百度地圖衝突的純淨解決方案

有這樣一個需求場景,要用百度地圖,且要放在Fragment中,百度地圖左右拖動就會和ViewPager的滑動事件衝突,這類似兩可拖動控制元件的衝突,網上的方法大致如下:

1、父View繼承ViewPager,重寫方法,如:

public class CustomViewPager extends ViewPager {  
  
    private boolean isCanScroll = true;  
  
    public CustomViewPager(Context context) {  
        super(context);  
    }  
  
    public CustomViewPager(Context context, AttributeSet attrs) {  
        super(context, attrs);  
    }  
  
    public void setScanScroll(boolean isCanScroll){  
        this.isCanScroll = isCanScroll;  
    }  
  
  
    @Override  
    public void scrollTo(int x, int y){  
        if (isCanScroll){  
            super.scrollTo(x, y);  
        }  
    }  

又如:
private boolean isCanScroll = true;
public void setScanScroll(boolean isCanScroll){  
       this.isCanScroll = isCanScroll;  
} 

@Override
public boolean onTouchEvent(MotionEvent ev) {
if (isCanScroll== false) {
return false;
} else {
return super.onTouchEvent(ev);
}

}

@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
if (isCanScroll== false) {
return false;
} else {
return super.onInterceptTouchEvent(ev);
}

}

又或者其它相似的實現,然後子View實現setOnTouchListener,在UP和DOWN中,通過設定isCanScroll的相反值,呼叫父View重寫的方法控制

2、父View不做處理,子View實現setOnTouchListener,在UP和DOWN中,分別呼叫下面的方法(用於通知父控制元件是否攔截事件):

getParent().requestDisallowInterceptTouchEvent(true or false) 

然而這兩種方法對於我的場景有很大弊端!因為定義了是否攔截Touch事件,當未攔截時,子View的OnTouch事件有效,但是一切換到攔截狀態,子View的OnTouch事件無效,即上面的程式碼會作廢,並會一直保持這個狀態,

後來,終於給我找到一篇文章(忘了名字),裡面有個方法:

@Override  
    protected boolean canScroll(View v, boolean checkV, int dx, int x, int y) {  
        // Not satisfied with this method of checking...  
        // working on a more robust solution  
        if(v.getClass().getName().equals("maps.j.b")) {  
            return true;  
        }  
}  
其中“maps.j.b”不知道什麼含義的,不是相當於魔數麼?

然後我加了個斷點,除錯進去一看,v.getClass()就是可觸發Scroll的控制元件的類名,如在MapView拖動,會先後兩次進來,分別是ViewPager和MapView,那“maps.j.b”這個魔數換成“com.baidu.mapapi.map.MapView”是否可以了?一試,果然!!!

於是,純淨的解決衝突方法就是:

public class ViewPagerCompat extends ViewPager {

	    public ViewPagerCompat(Context context) {  
	        super(context);  
	    }  
	  
	    public ViewPagerCompat(Context context, AttributeSet attrs) {  
	        super(context, attrs);  
	    }  
	    
	    
	    @Override  
	    protected boolean canScroll(View v, boolean checkV, int dx, int x, int y) {  
	        if(v.getClass().getName().equals("com.baidu.mapapi.map.MapView")) {  
	            return true;  
	        }  
	        //if(v instanceof MapView){  
	        //    return true;  
	        //}  
	        return super.canScroll(v, checkV, dx, x, y); 
	   } 
}

然後用這個ViewPagerCompat代替原來的ViewPager使用即可,從之衍生,其它類似元件衝突應該也可這樣處理