ViewPager與百度地圖衝突的純淨解決方案
阿新 • • 發佈:2018-12-30
有這樣一個需求場景,要用百度地圖,且要放在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使用即可,從之衍生,其它類似元件衝突應該也可這樣處理