你也可以插入一個呼叫處理touchevent
在dispatchTouchEvent
,但在這種情況下,你必須還覆蓋onTouchEvent
返回true,否則只有第一個MotionEvent
手勢的向下將被傳遞。
這是可觸摸的包裝容器:
<?xml version="1.0" encoding="utf-8"?>
<view xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
class="com.example.myapp.FragmentContainer$TouchableWrapper" />
和類:
public static class TouchableWrapper extends FrameLayout {
private GestureDetector gestureDetector;
public void setGestureDetector(GestureDetector gestureDetector) {
this.gestureDetector = gestureDetector;
}
// these constructors for the XML inflater
public TouchableWrapper(Context context) {
super(context);
}
public TouchableWrapper(Context context, AttributeSet attrs) {
super(context, attrs);
}
public TouchableWrapper(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
Log.d(TAG, "onInterceptTouchEvent " + event.toString());
return false; // true for intercept, false è default and pass on to children View
}
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
Log.d(TAG, "dispatchTouchEvent " + event.toString());
gestureDetector.onTouchEvent(event);
return super.dispatchTouchEvent(event);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
Log.d(TAG, "onTouchEvent " + event.toString());
return true; //return super.onTouchEvent(event);
}
}
這是GestureDetector
參考:
private GestureDetector gestureDetector;
此所述GestureListener
:
private GestureDetector.SimpleOnGestureListener sOGL = new GestureDetector.SimpleOnGestureListener() {
private static final int SWIPE_THRESHOLD = 100;
private static final int SWIPE_VELOCITY_THRESHOLD = 100;
@Override
public boolean onDown(MotionEvent e) {
return true;
}
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
boolean result = false;
try {
float diffY = e2.getY() - e1.getY();
float diffX = e2.getX() - e1.getX();
if (Math.abs(diffX) > Math.abs(diffY)) {
if (Math.abs(diffX) > SWIPE_THRESHOLD && Math.abs(velocityX) > SWIPE_VELOCITY_THRESHOLD) {
if (diffX > 0) {
goToRight(); // onSwipeRight();
} else {
goToLeft(); // onSwipeLeft();
}
}
result = true;
} else if (Math.abs(diffY) > SWIPE_THRESHOLD && Math.abs(velocityY) > SWIPE_VELOCITY_THRESHOLD) {
if (diffY > 0) {
// onSwipeBottom();
} else {
// onSwipeTop();
}
}
result = true;
} catch (Exception exception) {
exception.printStackTrace();
}
return result; // return false indicate event not handled
}
};
螞蟻這種加載可觸摸容器片段和包含片段:
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
Log.d(TAG, "onCreateView()");
View view = inflater.inflate(R.layout.fragmentcontainer, container, false);
gestureDetector = new GestureDetector(view.getContext(), sOGL);
((FragmentContainer.TouchableWrapper) view).setGestureDetector(gestureDetector);
FragmentManager fm = this.getFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.replace(R.id.pager, frag).commit();
return view;
}
假設我想在gridView的單元格內有一個horizontalScrollView,那麼如何使用這個解決方案在這種情況下不能很好地工作,並且允許我同時執行水平滾動和單擊/長按GridView的單元格? – 2014-01-18 14:32:54
這幫助我解決了一個ViewPager問題,我認爲我會爲後代拋出這個問題。我在ViewPager內部有必須附加OnClickListener/OnTouchListener的視圖。這些消耗運動事件導致父ViewPager不滾動。通過將這個技巧應用於包含視圖尋呼機的佈局,我可以將所有觸摸事件轉發給尋呼機(滾動器),而不管子是否將該事件用作點擊。 – mszaro 2015-03-13 21:10:52
我不認爲這是在onInterceptTouchEvent()中調用onTouchEvent()的「官方」方式,除非這是指某種破解。因爲如果從onInterceptTouchEvent()返回true,onTouchEvent()將被調用。 – KarolDepka 2016-01-16 20:36:03