通過繼承 ViewPager 並重寫觸摸事件分發方法,可實現「動態啟用/禁用滑動切換」功能。本文解析提供的 MyViewPager 代碼邏輯。
public class MyViewPager extends ViewPager {
private boolean noScroll = true; // 默認禁用滑動
public void setNoScroll(boolean noScroll) {
this.noScroll = noScroll;
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
if (noScroll) return false; // 不攔截,事件傳給子 View
return super.onInterceptTouchEvent(ev);
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
if (noScroll) return false; // 不處理觸摸
return super.onTouchEvent(ev);
}
// ... 其他方法保持默認
}
| 方法 | 返回 false 含義 | 返回 true 含義 |
|---|---|---|
onInterceptTouchEvent | 不攔截,事件繼續傳遞給子 View | 攔截,自己處理(ViewPager 內部滑動邏輯) |
onTouchEvent | 不消費事件,向上傳遞 | 消費事件,執行滑動切換 |
關鍵點:noScroll = true 時,兩個方法均返回 false,ViewPager 完全放棄觸摸處理,退化為靜態容器,頁面切換只能通過 setCurrentItem() 代碼控制。
noScroll 解決衝突。// 在子 View (如 RecyclerView) 中
parent.requestDisallowInterceptTouchEvent(true); // 禁止父 ViewPager 攔截
// 滑動結束後
parent.requestDisallowInterceptTouchEvent(false);
scrollTo 時調用 super.scrollTo 保證內部狀態一致。setCurrentItem 系列方法不受 noScroll 影響,仍可編程切換。onInterceptTouchEvent 中判斷 ev.getX() 方向。理解觸摸事件分發機制,即可靈活控制 ViewPager 的滑動行為。