Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> Android開發 >> 關於android開發 >> 如何禁止內部viewPager滑動,禁止viewPager滑動

如何禁止內部viewPager滑動,禁止viewPager滑動

編輯:關於android開發

如何禁止內部viewPager滑動,禁止viewPager滑動


眾所周知,viewPager是能夠滑動的,但有時候我們需要禁止它的滑動(微笑地面對*—……—*)。

情況是這樣的:

activity中有一個viewPager,viewPager中加入3個Fragment,第三個Fragment中又使用了一個viewPager,這個viewPager中又加入了幾個Fragment(本人不是受虐狂,僅僅是功能需要)。如圖:

想實現的功能:

點擊activity的圖標或者滑動的時候能夠切換第一個viewPager中的Fragment,點擊Fragment3中的圖標能夠切換第二個viewPager裡的Fragment,但是禁止這個viewPager滑動第二個viewPager裡的Fragment1裡面有一個listView(有下拉刷新功能),要能夠上下滑動不受影響。

關鍵就是禁止內部viewPager滑動,但是其它的功能不受影響。

呵呵,已經元氣大傷......

探索過程已經不想吐槽。

 

這個問題涉及到事件的分發機制,需要重寫viewPager。那麼到底該重寫哪個viewPager呢?

首先分析一下這個問題的解決過程:

1.要禁止裡面的viewPager左右滑動,那麼即是說當我們左右滑動的時候,外面的viewPager要攔截事件,當我們上下滑動的時候外面的viewPager不能攔截事件,這樣事件才能傳遞到內部的viewPager,內部viewPager裡的fragment包含的listView才能上下滑動。

2.當然點擊事件也不能夠攔截,這樣點擊Fragment3的圖標才能切換內部viewPager裡面的Fragment。

3.由於內部viewPager在Fragment3,所以我們在外部的viewPager切換到item3的時候再做1,2步的處理。

 

在這裡重寫外部viewPager會比較方便,即我們用外部攔截法。

接下來請看外部攔截神功。

import android.content.Context;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import neo.door.usermanager.UserManager;

public class MyViewPager extends ViewPager {
    private int mFirstX =0,mFirstY=0;
    private String TAG = "MyViewPager";

    public MyViewPager(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent event) {
        if(this.getCurrentItem()==2) //如果滑動到了第三個Fragment
        {
            boolean isIntercept=false;
            int x=(int) event.getX();
            int y=(int) event.getY();
            Log.e(TAG, "onInterceptTouchEvent");
            switch (event.getAction()) {
/**
    * 父容器必須返回false,即不攔截ACTION_DOWN事件,
    * 否則後續的ACTION_MOVE,ACTION_UP事件都會直接交給父容器處理,
    * 事件沒辦法再傳遞給子元素了
    */
case MotionEvent.ACTION_DOWN:
Log.e(TAG, "onInterceptTouchEvent_ACTION_DOWN"); isIntercept=false;
break;
/**
     * 根據需要覺定是否攔截
     */
case MotionEvent.ACTION_MOVE: if (Math.abs(x - mFirstX) > Math.abs(y - mFirstY)) //左右滑動 { isIntercept = true; if(正在下拉) //想刷新時候(若不寫這一步,如果我們向下滑到一半突然左右滑動那麼listView就會卡在中間狀態不動。) isIntercept=false; } else //上下滑動 { isIntercept = false; } Log.e(TAG, "onInterceptTouchEvent_ACTION_MOVE"); break;
/**
     * 必須返回false,因為ACTION_UP本身沒有太大意義。
 * 
     */
case MotionEvent.ACTION_UP: isIntercept=false; Log.e(TAG, "onInterceptTouchEvent_ACTION_UP"); break; default: break; } mFirstX=x; mFirstY=y; Log.e(TAG, "onInterceptTouchEvent_return"); return isIntercept; } else //如果沒有滑動到了第三個Fragment,不作處理 return super.onInterceptTouchEvent(event); } }

首先要知道 onInterceptTouchEvent這個方法,返回true代表攔截,返回false代表不攔截。

注意:

1.ACTION_UP。

考慮一種情況:若是事件交給子元素處理,而父容器在ACTION_UP的時候返回了true,那麼子元素就會無法收到ACTION_UP事件,子元素的onClik事件無法觸發,也就是說在這道題中,Fragment3的圖標將無法點擊,並且listView的滑動會在手指離開屏幕的時候停留在中間態。

父容器比較特殊,一旦它開始攔截任何一個事件,那麼後續事件都會交給它處理,ACTION_UP作為最後一個事件也一樣可以傳遞給父容器,即便父容器的onInterceptTouchEvent方法在ACTION_UP時返回了false。

2.ACTION_MOVE之中。

假如我們要刷新listView,在我們下拉listView的時候手指突然間左滑或者右滑,那麼listView就會停留在中間狀態。放開手也不會回去,為什麼呢?

原因是這樣的:在我們手指下滑的時候,在ACTION_MOVE中判斷後不符合 (Math.abs(x - mFirstX) > Math.abs(y - mFirstY)),所以父容器即外部的viewPager返回false,不攔截事件,listView能夠滑動。但是當我們在下滑的時候突然間左右滑,那麼在ACTION_MOVE中判斷後符合 (Math.abs(x - mFirstX) > Math.abs(y - mFirstY)),所以父容器即外部的viewPager返回true,攔截了事件,所以listView無法完成事件,只是停留在了手指左右滑動之前的那個瞬間狀態。(這種情況最後的ACTION_UP沒有執行,這點還不理解)

所以我們要加個判斷,判斷listview是否正要下拉刷新,如果是,不要攔截事件。

至於判斷方法挺多的,就不再寫。

【寫到這裡,也就差不多了,以後若是有得補充再來補充吧。@—^—@】

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved