1. 程式人生 > >APP實用開發——廣告輪播圖

APP實用開發——廣告輪播圖

這裡寫圖片描述

ViewPager是一個常用的android元件,不過通常我們使用ViewPager的時候不能實現左右無限迴圈滑動,在滑到邊界的時候會看到一個不能翻頁的動畫,可能影響使用者體驗。此外,某些區域性的ViewPager(例如展示廣告或者公告之類的ViewPager),可能需要自動輪播的效果,即使用者在不用滑動的情況下就能夠看到其他頁面的資訊。

迴圈滑動效果的實現:PagerAdapter
我們知道ViewPager自帶的滑動效果非常出色,因此我們基本不需要處理這個滑動,只處理內容的顯示。而內容的顯示是由Adapter控制的,因此這裡重點就是這個Adapter了。為簡單起見,本例的每個View直接是一張圖片。下面是Adapter的程式碼:

private class ImageAdapter extends PagerAdapter{  

        private ArrayList<ImageView> viewlist;  

        public ImageAdapter(ArrayList<ImageView> viewlist) {  
            this.viewlist = viewlist;  
        }  

        @Override  
        public int getCount() {  
            //設定成最大,使使用者看不到邊界  
return Integer.MAX_VALUE; } @Override public boolean isViewFromObject(View arg0, Object arg1) { return arg0==arg1; } @Override public void destroyItem(ViewGroup container, int position, Object object) { //Warning:不要在這裡呼叫removeView
} @Override public Object instantiateItem(ViewGroup container, int position) { //對ViewPager頁號求模取出View列表中要顯示的項 position %= viewlist.size(); if (position<0){ position = viewlist.size()+position; } ImageView view = viewlist.get(position); //如果View已經在之前新增到了一個父元件,則必須先remove,否則會丟擲IllegalStateException。 ViewParent vp =view.getParent(); if (vp!=null){ ViewGroup parent = (ViewGroup)vp; parent.removeView(view); } container.addView(view); //add listeners here if necessary return view; } }

這裡有幾個地方需要注意:

getCount() 方法的返回值:這個值直接關係到ViewPager的“邊界”,因此當我們把它設定為Integer.MAX_VALUE之後,使用者基本就看不到這個邊界了(估計滑到這裡的時候電池已經掛了吧o_O)。當然,通常情況下設定為100倍實際內容個數也是可以的,之前看的某個實現就是這麼幹的。

instantiateItem() 方法position的處理:由於我們設定了count為 Integer.MAX_VALUE,因此這個position的取值範圍很大很大,但我們實際要顯示的內容肯定沒這麼多(往往只有幾項),所以這裡肯定會有求模操作。但是,簡單的求模會出現問題:考慮使用者向左滑的情形,則position可能會出現負值。所以我們需要對負值再處理一次,使其落在正確的區間內。

destroyItem() 方法:由於我們在instantiateItem()方法中已經處理了remove的邏輯,因此這裡並不需要處理。實際上,實驗表明這裡如果加上了remove的呼叫,則會出現ViewPager的內容為空的情況。

輪播效果的實現:使用Handler進行更新

這裡我定義了一個Handler來處理ViewPager的輪播。所謂的“輪播”效果實現起來是這樣的:每隔一定時間(這裡是3秒)切換一次顯示的頁面。通過控制各頁面以一定順序迴圈播放,就達到了輪播的效果。為此,我們可以使用Handler的sendEmptyMessageDelayed()方法來實現定時更新,並
注意使用者也可能會對帶有輪播效果的ViewPager手動進行滑動操作,因此我認為使用者這時候是希望檢視指定頁面的,這時候應該取消輪播。下面是這個Handler的實現:

案例1

這裡寫圖片描述

一、ViewPager填充圖片
1.1 佈局中申明
由於是顯示廣告條,所以高度要固定住

 <android.support.v4.view.ViewPager
      android:id="@+id/viewpager"
      android:layout_width="match_parent"
      android:layout_height="120dp"/>

1.2 程式碼中設定頁面資料
準備顯示圖片控制元件的集合

 // 準備顯示的圖片集合
  mList = new ArrayList<>();
  for (int i = 0; i < mImages.length; i++) {
      ImageView imageView = new ImageView(this);
      // 將圖片設定到ImageView控制元件上
      imageView.setImageResource(mImages[i]);

      // 將ImageView控制元件新增到集合
      mList.add(imageView);
  }

自定義類書寫介面卡

 @Override
  public Object instantiateItem(ViewGroup container, int position) {
      // return super.instantiateItem(container, position);
      // 將圖片控制元件新增到容器
      container.addView(mList.get(position));

      // 返回
      return mList.get(position);
  }

二、底部小圓點顯示邏輯
原理分析:底部的小圓點時浮動在ViewPager上面的的,所以應該是一個RelativeLayout佈局。
ViewPager頁面切換時小圓點的顏色不一樣,所以需要對小圓點做選擇器,並且對ViewPager進行監聽。

2.1 佈局申明

需要用一個RelativeLayout將ViewPager和包裹圓點的LinearLayout包裹起來

 <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="120dp">

        <android.support.v4.view.ViewPager
            android:id="@+id/viewpager"
            android:layout_width="match_parent"
            android:layout_height="120dp"/>

        <LinearLayout
            android:id="@+id/pointgroup"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true"
          android:layout_centerHorizontal="true"
            android:layout_marginBottom="3dp"
            android:orientation="horizontal">
        </LinearLayout>
    </RelativeLayout>

2.2 製作小圓點顏色選擇器

選擇器的選中狀態應該設定為selected,因為對ViewPager監聽時可以設定selected的屬性

 <selector xmlns:android="http://schemas.android.com/apk/res/android">
      <item android:drawable="@drawable/shape_point_normal" android:state_selected="false"/>
      <item android:drawable="@drawable/shape_point_selected" android:state_selected="true"/>
  </selector>

  <shape xmlns:android="http://schemas.android.com/apk/res/android"
         android:shape="oval">
      <solid android:color="#66000000"/>
  </shape

  <shape xmlns:android="http://schemas.android.com/apk/res/android"
      android:shape="oval">
      <solid android:color="#FFFFFF"/>
  </shape>

2.3 將小圓點新增到LinearLayout容器

小圓點其實就是一個ImageView,所以在做出ViewPager的頁面圖片時,一起把小圓點也做了
初始化ImageView新增到LinearLayout之前,需要設定小圓點的佈局引數,包括位置和大小

 LinearLayout pointGroup = (LinearLayout) findViewById(R.id.pointgroup);

  for (int i = 0; i < mImages.length; i++) {
      // 製作底部小圓點
      ImageView pointImage = new ImageView(this);
      pointImage.setImageResource(R.drawable.shape_point_selector);

      // 設定小圓點的佈局引數
      int PointSize = getResources().getDimensionPixelSize(R.dimen.point_size);
      LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(PointSize, PointSize);

      if (i > 0) {
          params.leftMargin = getResources().getDimensionPixelSize(R.dimen.point_margin);
          pointImage.setSelected(false);
      } else {
          pointImage.setSelected(true);
      }
      pointImage.setLayoutParams(params);
      // 新增到容器裡
      pointGroup.addView(pointImage);
     }

三、小圓點隨著ViewPager切換移動

其實就是對ViewPager設定滑動監聽,當滑動到每一頁時就設定小圓點為選中狀態,這樣小圓點就顯示白色,其他頁面就設定為未選中狀態顯示灰色。

// 對ViewPager設定滑動監聽
  viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
      @Override
      public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

      }

      int lastPosition;
      @Override
      public void onPageSelected(int position) {
          // 頁面被選中
          // 設定當前頁面選中
          pointGroup.getChildAt(position).setSelected(true);
          // 設定前一頁不選中
          pointGroup.getChildAt(lastPosition).setSelected(false);

          // 替換位置
          lastPosition = position;

      }

      @Override
      public void onPageScrollStateChanged(int state) {

      }
  });

經過前面的三步設定後就能顯示一個簡單的廣告條了,這裡再對其新增一個滑動到最後一頁後再滑還能滑動到首頁的功能。
四、無限滑動的ViewPager
實現原理: ViewPager之所以滑動到左右能顯示頁面,其實是因為左右都存在即將要顯示的頁面。當左右有很多頁面時我們就能一直滑動,沒有時就不能滑動。所以原理就是讓ViewPager的左右都有很多的頁面。
4.1 修改getCount方法

ViewPager能顯示多少個頁面全由getCount方法說了算,所以我們首先要改造它。

 @Override
  public int getCount() {
      // 返回整數的最大值
      return Integer.MAX_VALUE;
  }

4.2 修改instantiateItem方法

因為position變了,所以顯示的位置也變了,這裡需要進行取%運算,來還原position。

// 修改position
  position = position % mList.size();

4.3 修改ViewPager監聽器裡的onPageSelected

用到了position就要修改。

 position = position % mList.size();

修改之後,ViewPager當前頁的右邊就有了無數的頁面,但是因為%了mList.size(),就只會顯示mList.size()的大小,這樣就實現了無限滑動輪播
五、無限自動輪播的廣告圖
實現原理:在前面四步的基礎上,在程式碼裡新增一個Handler,不斷的給自己發訊息就好了。

mHandler.postDelayed(new Runnable() {
        @Override
        public void run() {
            int currentPosition = viewPager.getCurrentItem();

            if(currentPosition == viewPager.getAdapter().getCount() - 1){
                // 最後一頁
                viewPager.setCurrentItem(0);
            }else{
                viewPager.setCurrentItem(currentPosition + 1);
            }

            // 一直給自己發訊息
            mHandler.postDelayed(this,5000);
        }
    },5000);

案例2

這裡寫圖片描述

public class RoolViewPager extends ViewPager {

    private int downX;
    private int downY;

    public RoolViewPager(Context context, AttributeSet attrs) {
        super(context, attrs);
        // TODO Auto-generated constructor stub
    }

    public RoolViewPager(Context context) {
        super(context);
        // TODO Auto-generated constructor stub
    }

    //事件分發的
    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        //請求父控制元件不要攔截事件,true:不攔截,false:攔截
        //getParent().requestDisallowInterceptTouchEvent(disallowIntercept);
        //1.需要判斷是左右滑動還是上下滑動,因為只有左右才是viewpager手動滑動的操作
        switch (ev.getAction()) {
        case MotionEvent.ACTION_DOWN:
            //getParent().requestDisallowInterceptTouchEvent(false);
            //獲取按下的x和y的座標
            downX = (int) ev.getX();
            downY = (int) ev.getY();
            break;
        case MotionEvent.ACTION_MOVE:
            //獲取移動的x和y的座標
            int moveX = (int) ev.getX();
            int moveY = (int) ev.getY();
            //判斷是上下還是左右滑動
            if (Math.abs(moveX-downX) > Math.abs(moveY-downY)) {
                //左右
                //從右往左,如果是最後一個條目,父控制元件攔截事件,實現切換介面的操作,如果不是最後一個條目,切換下一張圖片
                //getAdapter() : 獲取ViewPager設定的adapter
                if (downX - moveX > 0 && getCurrentItem() == getAdapter().getCount()-1) {
                    getParent().requestDisallowInterceptTouchEvent(false);
                }else if(downX - moveX > 0 && getCurrentItem() < getAdapter().getCount()-1){
                    getParent().requestDisallowInterceptTouchEvent(true);
                }
                //從左往右,如果是第一個條目,父控制元件攔截事件,開啟側拉選單,如果不是第一個條目,切換到上一張圖片
                else if(downX - moveX < 0 && getCurrentItem() == 0){
                    getParent().requestDisallowInterceptTouchEvent(false);
                }else if(downX - moveX < 0 && getCurrentItem() > 0){
                    getParent().requestDisallowInterceptTouchEvent(true);
                }

            }else{
                //上下
                getParent().requestDisallowInterceptTouchEvent(false);
            }

            break;
        case MotionEvent.ACTION_UP:

            break;
        }
        return super.dispatchTouchEvent(ev);
    }

}
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="185dp" >

    <!-- xmlns:app="http://schemas.android.com/apk/res/com.itheima.zhbj97" -->

    <com.itheima.zhbj97.ui.RoolViewPager
        android:id="@+id/menunewscenteritem_vp_viewpager"
        android:layout_width="match_parent"
        android:layout_height="185dp"
        ></com.itheima.zhbj97.ui.RoolViewPager>
    <!-- layout_alignBottom : 在哪個控制元件的底部 -->
    <RelativeLayout 
        android:layout_width="match_parent"
        android:layout_height="30dp"
        android:background="#aa000000"
        android:layout_alignBottom="@+id/menunewscenteritem_vp_viewpager"
        >
        <TextView 
            android:id="@+id/menunewscenteritem_tv_title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="蝸居生活"
            android:textSize="18sp"
            android:textColor="#FFFFFF"
            android:layout_centerVertical="true"
            android:layout_marginLeft="10dp"
            />
         <!-- radius : 點的半徑 
              fillColor :點的填充顏色
              pageColor : 介面的點的顏色
              strokeColor : 邊框的顏色
              strokeWidth : 邊框的寬度
         -->
         <com.viewpagerindicator.CirclePageIndicator
            android:id="@+id/menunewscenteritem_cpi_indicator"
            android:padding="10dip"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:radius="3dp"
            app:fillColor="#FF0000"
            app:pageColor="#FFFFFF"
            app:strokeWidth="0dp"
            android:layout_centerVertical="true"
            android:layout_alignParentRight="true"
            android:layout_marginRight="10dp"
        />
    </RelativeLayout>

</RelativeLayout>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:ptr="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <!-- scrollbars : 設定listview的滾動條 -->
    <com.handmark.pulltorefresh.library.PullToRefreshListView 
        android:id="@+id/menunewscenteritem_lv_listview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:divider="@android:color/darker_gray"
        android:dividerHeight="1dp"
        android:listSelector="@android:color/transparent"
        android:scrollbars="none"
        ptr:ptrMode="both"
        ></com.handmark.pulltorefresh.library.PullToRefreshListView>

</LinearLayout>
mViewPagerView = View.inflate(activity, R.layout.menunewscenter_viewpager, null);
        mListViewPagerView = View.inflate(activity, R.layout.menunewscenteritem_listview, null);

        //初始化控制元件
        mViewPager = (RoolViewPager) mViewPagerView.findViewById(R.id.menunewscenteritem_vp_viewpager);
        mTitle = (TextView) mViewPagerView.findViewById(R.id.menunewscenteritem_tv_title);
        mIndicator = (CirclePageIndicator) mViewPagerView.findViewById(R.id.menunewscenteritem_cpi_indicator);

        mPullListView = (PullToRefreshListView) mListViewPagerView.findViewById(R.id.menunewscenteritem_lv_listview);
1.設定VIewPager的adapter
    private void showMsg(NewBean newBean) {

        //1.ViewPager的資料
        if (newBean.data.topnews.size() > 0) {

            ....                

            //1.2.通過viewpager展示資料
            if (myadapter == null) {
                myadapter = new Myadapter();
                mViewPager.setAdapter(myadapter);
            }else{
                myadapter.notifyDataSetChanged();
            }

        }
        //2.ListView的資料
    }

2.adapter的操作

    @Override
    public Object instantiateItem(ViewGroup container, int position) {
        View rootView = View.inflate(activity, R.layout.menunewsceteritem_viewpager_item, null);
        ImageView mIcon = (ImageView) rootView.findViewById(R.id.item_iv_icon);

        //因為圖片是在伺服器中,不在本地,所以需要從伺服器獲取圖片,展示在imageView
        //通過圖片的路徑請求伺服器中的圖片,存放到相應的imageView中
        Glide.with(activity.getApplicationContext()).load(imagerUrls.get(position)).into(mIcon);

        //將圖片所在的佈局新增到ViewPager中展示
        container.addView(rootView);

        return rootView;
    }

ViewPager的介面點和文字的初始化操作

private void showMsg(NewBean newBean) {

    //1.ViewPager的資料
    if (newBean.data.topnews.size() > 0) {

        ...

        //1.3.將viewpager和點的indicator關聯
        mIndicator.setViewPager(mViewPager);
        mIndicator.setSnap(true);//快照,使用快照的方式顯示點

        //1.4.設定預設顯示第一張圖片,第一個文字,第一個點
        mTitle.setText(titles.get(0));
        mIndicator.onPageSelected(0);
        mViewPager.setCurrentItem(0);//設定viewpager當前顯示的介面,item:條目的索引
    }
    //2.ListView的資料
}

填充listview的資料將ViewPager的佈局作為listView的頭條目展示

1.將ViewPager的佈局作為listview的頭條目展示
    private void showMsg(NewBean newBean) {

        //1.ViewPager的資料
        if (newBean.data.topnews.size() > 0) {

            ....

            //1.5.將ViewPager所在的佈局,新增到listView中
            //獲取listview的頭條目的個數
            if (mListView.getHeaderViewsCount()<1) {
                mListView.addHeaderView(mViewPagerView);//給listview新增頭條目
            }
        }
        //2.ListView的資料


    }
2.填充listview資料
    private void showMsg(NewBean newBean) {


        .....       

        //2.ListView的資料
        if (newBean.data.news.size() > 0) {
            mNews = newBean.data.news;

            //設定listview的adapter展示資料
            if (listViewAdapter == null) {
                listViewAdapter = new MyListViewAdapter();
                mListView.setAdapter(listViewAdapter);
            }else{
                listViewAdapter.notifyDataSetChanged();
            }

        }

    }

ViewPager自動滑動操作

核心理念:每個一段時間,viewpager切換到下一個介面

1.通過handler設定viewpager的自動滑動操作
    //因為showMsg方法實在processjson方法中呼叫的,而processJson是在快取和獲取最新資料的時候都會呼叫,最終會造成傳送兩個延遲訊息,但是隻需要一個延遲訊息就可以了
        if (handler == null) {
            handler = new Handler(){
                public void handleMessage(android.os.Message msg) {
                    //viewpager切換下一個介面的操作
                    //首先需要知道當前顯示的介面
                    int currentItem = mViewPager.getCurrentItem();//獲取當前顯示介面的索引
                    //然後計算下一個介面的索引
                    //判斷是否切換到最後一個介面,如果是最後一個介面了,切換回第一個介面
                    if (currentItem == imagerUrls.size()-1) {
                        currentItem=0;
                    }else{
                        currentItem++;  
                    }
                    //設定viewpager顯示下一個介面
                    mViewPager.setCurrentItem(currentItem);
                    //切換一次完成,還要緊接著切換第二次
                    handler.sendEmptyMessageDelayed(0, 3000);
                };
            };
            handler.sendEmptyMessageDelayed(0, 3000);//只有執行此方法,才會傳送延遲訊息,不執行就不傳送
        }
2.設定viewpager的介面切換監聽,實現切換介面顯示介面對應的文字
        //監聽viewpager的介面切換,實現切換一個介面顯示一個介面對應的文字
        mViewPager.addOnPageChangeListener(new OnPageChangeListener() {

            @Override
            public void onPageSelected(int position) {
                mTitle.setText(titles.get(position));
            }

            @Override
            public void onPageScrolled(int position, float positionOffset,
                    int positionOffsetPixels) {
                // TODO Auto-generated method stub

            }

            @Override
            public void onPageScrollStateChanged(int state) {
                // TODO Auto-generated method stub

            }
        });

viewpager的手動滑動

當滑動到小viewpager的最後一個介面的時候,外面的viewpager要將小的viewpager的觸控事件攔截,當滑動小的viewpager的不是最後一個介面的時候,外面的viewpager不攔截小viewpager的觸控事件
讓小viewpager進行滑動操作

建立自定義Viewpager進行操作

//事件分發的
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
    //請求父控制元件不要攔截事件,true:不攔截,false:攔截
    //getParent().requestDisallowInterceptTouchEvent(disallowIntercept);
    //1.需要判斷是左右滑動還是上下滑動,因為只有左右才是viewpager手動滑動的操作
    switch (ev.getAction()) {
    case MotionEvent.ACTION_DOWN:
        //getParent().requestDisallowInterceptTouchEvent(false);
        //獲取按下的x和y的座標
        downX = (int) ev.getX();
        downY = (int) ev.getY();
        break;
    case MotionEvent.ACTION_MOVE:
        //獲取移動的x和y的座標
        int moveX = (int) ev.getX();
        int moveY = (int) ev.getY();
        //判斷是上下還是左右滑動
        if (Math.abs(moveX-downX) > Math.abs(moveY-downY)) {
            //左右
            //從右往左,如果是最後一個條目,父控制元件攔截事件,實現切換介面的操作,如果不是最後一個條目,切換下一張圖片
            //getAdapter() : 獲取ViewPager設定的adapter
            if (downX - moveX > 0 && getCurrentItem() == getAdapter().getCount()-1) {
                getParent().requestDisallowInterceptTouchEvent(false);
            }else if(downX - moveX > 0 && getCurrentItem() < getAdapter().getCount()-1){
                getParent().requestDisallowInterceptTouchEvent(true);
            }
            //從左往右,如果是第一個條目,父控制元件攔截事件,開啟側拉選單,如果不是第一個條目,切換到上一張圖片
            else if(downX - moveX < 0 && getCurrentItem() == 0){
                getParent().requestDisallowInterceptTouchEvent(false);
            }else if(downX - moveX < 0 && getCurrentItem() > 0){
                getParent().requestDisallowInterceptTouchEvent(true);
            }

        }else{
            //上下
            getParent().requestDisallowInterceptTouchEvent(false);
        }

        break;
    case MotionEvent.ACTION_UP:

        break;
    }
    return super.dispatchTouchEvent(ev);
}

ViewPager和View的事件響應規則

如果是緩慢的移動很短的距離,viewpager和view的事件都會執行
如果是快速滑動很長的距離,view的事件會執行cancel事件,結束view的觸控操作,只去viewpager的事件

具體操作
    //設定view的觸控事件事件,實現按下viewpager停止自動滑動,擡起,viewpager重新進行自動滑動操作
        rootView.setOnTouchListener(new OnTouchListener() {

            @Override
            public boolean onTouch(View v, MotionEvent event) {
                switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    //按下viewpager停止滑動
                    handler.removeCallbacksAndMessages(null);//取消handler傳送延遲訊息,如果是null,全部handler都會被取消傳送訊息
                    break;
                case MotionEvent.ACTION_UP:
                    //擡起viewpager重新滑動
                    handler.sendEmptyMessageDelayed(0, 3000);
                    break;
                case MotionEvent.ACTION_CANCEL:
                    //view的事件取消執行的操作
                    handler.sendEmptyMessageDelayed(0, 3000);
                    break;
                }

                //如果想要事件執行,返回true,返回事件不執行
                return true;
            }
        });

自定義RoolViewPager

public class RoolViewPager extends ViewPager {

    private int downX;
    private int downY;

    public RoolViewPager(Context context, AttributeSet attrs) {
        super(context, attrs);
        // TODO Auto-generated constructor stub
    }

    public RoolViewPager(Context context) {
        super(context);
        // TODO Auto-generated constructor stub
    }

    //事件分發的
    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        //請求父控制元件不要攔截事件,true:不攔截,false:攔截
        //getParent().requestDisallowInterceptTouchEvent(disallowIntercept);
        //1.需要判斷是左右滑動還是上下滑動,因為只有左右才是viewpager手動滑動的操作
        switch (ev.getAction()) {
        case MotionEvent.ACTION_DOWN:
            //getParent().requestDisallowInterceptTouchEvent(false);
            //獲取按下的x和y的座標
            downX = (int) ev.getX();
            downY = (int) ev.getY();
            break;
        case MotionEvent.ACTION_MOVE:
            //獲取移動的x和y的座標
            int moveX = (int) ev.getX();
            int moveY = (int) ev.getY();
            //判斷是上下還是左右滑動
            if (Math.abs(moveX-downX) > Math.abs(moveY-downY)) {
                //左右
                //從右往左,如果是最後一個條目,父控制元件攔截事件,實現切換介面的操作,如果不是最後一個條目,切換下一張圖片
                //getAdapter() : 獲取ViewPager設定的adapter
                if (downX - moveX > 0 && getCurrentItem() == getAdapter().getCount()-1) {
                    getParent().requestDisallowInterceptTouchEvent(false);
                }else if(downX - moveX > 0 && getCurrentItem() < getAdapter().getCount()-1){
                    getParent().requestDisallowInterceptTouchEvent(true);
                }
                //從左往右,如果是第一個條目,父控制元件攔截事件,開啟側拉選單,如果不是第一個條目,切換到上一張圖片
                else if(downX - moveX < 0 && getCurrentItem() == 0){
                    getParent().requestDisallowInterceptTouchEvent(false);
                }else if(downX - moveX < 0 && getCurrentItem() > 0){
                    getParent().requestDisallowInterceptTouchEvent(true);
                }

            }else{
                //上下
                getParent().requestDisallowInterceptTouchEvent(false);
            }

            break;
        case MotionEvent.ACTION_UP:

            break;
        }
        return super.dispatchTouchEvent(ev);
    }
}

xml使用

佈局檔案中使用
<com.itheima.zhbj97.ui.RoolViewPager
    android:id="@+id/menunewscenteritem_vp_viewpager"
    android:layout_width="match_parent"
    android:layout_height="185dp"
    ></com.itheima.zhbj97.ui.RoolViewPager>