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

來源:互聯網
上載者:User

如何禁止內部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是否正要下拉重新整理,如果是,不要攔截事件。

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

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

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.