Android——ViewPager和內部view之間的事件分發及輪播圖

來源:互聯網
上載者:User

Android——ViewPager和內部view之間的事件分發及輪播圖

viewpager 在滑動的過程中是如何觸發view身上的事件的,換句話說,viewpager在滑動的過程中到底是滑動的它裡面的view,還是滑動的viewpager本身?

一、範例程式碼:

1、自訂ViewPager:MyViewPager,重新dispatchTouchEvent方法,添加一些事件處理的log資訊。

package com.example.viewpagerdemo;import android.content.Context;import android.support.v4.view.ViewPager;import android.util.AttributeSet;import android.util.Log;import android.view.MotionEvent;public class MyViewPager extends ViewPager {    private String TAG = "viewpagertest";    public MyViewPager(Context context, AttributeSet attrs) {        super(context, attrs);    }    @Override    public boolean dispatchTouchEvent(MotionEvent ev) {        switch (ev.getAction()) {        case MotionEvent.ACTION_DOWN:            Log.i(TAG , "===MyViewPager MotionEvent.ACTION_DOWN===");            break;        case MotionEvent.ACTION_MOVE:            Log.i(TAG , "===MyViewPager MotionEvent.ACTION_MOVE===");            break;        case MotionEvent.ACTION_UP:            Log.i(TAG , "===MyViewPager MotionEvent.ACTION_UP===");            break;        case MotionEvent.ACTION_CANCEL:            Log.i(TAG , "===MyViewPager MotionEvent.ACTION_CANCEL===");            break;        }        return super.dispatchTouchEvent(ev);    }}

2、在activity中設定viewpager的資料配接器,給view添加touch事件監聽器,添加事件處理的log資訊。

package com.example.viewpagerdemo;import android.app.Activity;import android.os.Bundle;import android.support.v4.view.PagerAdapter;import android.util.Log;import android.view.MotionEvent;import android.view.View;import android.view.View.OnTouchListener;import android.view.ViewGroup;import android.view.Window;import android.widget.ImageView;public class MainActivity extends Activity {    private String TAG = "viewpagertest";    private Integer[] imgList = {R.drawable.first,R.drawable.second,R.drawable.third,R.drawable.four};    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        requestWindowFeature(Window.FEATURE_NO_TITLE);        setContentView(R.layout.activity_main);        MyViewPager viewPager = (MyViewPager) findViewById(R.id.myviewpager);        viewPager.setAdapter(new MyAdapter());    }    class MyAdapter extends PagerAdapter {        @Override        public int getCount() {            return 4;        }        @Override        public boolean isViewFromObject(View arg0, Object arg1) {            return arg0 == arg1;        }        @Override        public Object instantiateItem(ViewGroup container, int position) {            View view = View.inflate(getApplicationContext(), R.layout.view_item, null);            ImageView imageView = (ImageView) view.findViewById(R.id.iv);            imageView.setBackgroundResource(imgList[position]);            view.setOnTouchListener(new OnTouchListener() {                @Override                public boolean onTouch(View v, MotionEvent ev) {                    switch (ev.getAction()) {                    case MotionEvent.ACTION_DOWN:                        Log.d(TAG , "===view MotionEvent.ACTION_DOWN===");                        break;                    case MotionEvent.ACTION_MOVE:                        Log.d(TAG , "===view MotionEvent.ACTION_MOVE===");                        break;                    case MotionEvent.ACTION_UP:                        Log.d(TAG , "===view MotionEvent.ACTION_UP===");                        break;                    case MotionEvent.ACTION_CANCEL:                        Log.d(TAG , "===view MotionEvent.ACTION_CANCEL===");                        break;                    }                    return true;                }            });            ((MyViewPager)container).addView(view);            return view;        }        @Override        public void destroyItem(ViewGroup container, int position, Object object) {            ((MyViewPager)container).removeView((View) object);        }    }}

二、事件分發測試:

1、點擊:

logcat:

分析:
內部view的setOnTouchListener的onTouch()方法返回true,ACTION_DOWN、ACTION_UP事件都由內部view消費掉了。

2、滑動(滑一點點,ViewPager未改變):

logcat:

分析:
內部view的setOnTouchListener的onTouch()方法返回true,ACTION_DOWN、ACTION_MOVE、ACTION_UP事件都由內部view消費掉了。

3、滑動:

logcat:

分析:內部view的ACTION_CANCEL事件被觸發,後續事件被外部viewpager接管。

總結:<喎?http://www.bkjia.com/kf/ware/vc/" target="_blank" class="keylink">vc3Ryb25nPjxiciAvPg0Kx7DM4aO6xNqyv3ZpZXe1xHNldE9uVG91Y2hMaXN0ZW5lcrXEb25Ub3VjaCgpt723qLe1u9h0cnVloaOjqLHtyr64w1ZpZXfE2rK/z/u7r7X0wcvL+dPQysK8/qOpPGJyIC8+DQq7rLavdmlld3BhZ2VyyKXH0Lu7srvNrLXEaXRlbcqxo7o8YnIgLz4NCrWxu6y2r7XEvuDA68O709C077W9wdm959a1o6jNqLOjdmlld3BhZ2Vyu7nU2rWxx7BpdGVto6mjrMrCvP674dK71rHX99PD1NrE2rK/tcR2aWV3ye3Jz6OsPGJyIC8+DQo8c3Ryb25nPrWxu6y2r7XEvuDA66Ooz/HL2LXjo6m077W90ru2qLen1rWjqMHZvefWtaOpyrE8L3N0cm9uZz4ozaizo3ZpZXdwYWdlctLRu6y1vc/C0ru49ml0ZW0po6w8c3Ryb25nPrvhtKW3osTasr92aWV3tcRBQ1RJT05fQ0FOQ0VMysK8/jwvc3Ryb25nPqGjuvPQ+LXEQUNUSU9OX01PVkWhokFDVElPTl9VULa8sbt2aWV3cGFnZXK907nco6zX99PD1NrN4sPmtcR2aWV3cGFnZXLJ7cnPoaM8L3A+DQo8cD7I/aGisLjA/TxiciAvPg0KzbzGrMLWsqXQp7n7zbyjujxiciAvPg0KPGltZyBhbHQ9"這裡寫圖片描述" src="http://www.bkjia.com/uploads/allimg/150627/0422504525-6.gif" title="\" />
自訂輪播圖viewpager代碼:

package com.example.zwdzjs.view;import java.util.List;import android.content.Context;import android.os.Handler;import android.os.Message;import android.support.v4.view.PagerAdapter;import android.support.v4.view.ViewPager;import android.view.MotionEvent;import android.view.View;import android.view.ViewGroup;import android.widget.ImageView;import android.widget.TextView;import com.example.logutil.LogUtil;import com.example.zwdzjs.R;import com.lidroid.xutils.BitmapUtils;public class RollViewPager extends ViewPager { private String TAG = "RollViewPager"; private Context context; private List titleList; private List urlImgList; private TextView top_news_title; private MyRollViewPagerAdapter adapter; private BitmapUtils bitmapUtils; private int currentItem = 0; private OnViewPagerItemClickListener onItemClickListener; private Handler handler = new Handler(){ @Override public void handleMessage(Message msg) { RollViewPager.this.setCurrentItem(currentItem); startRoll(); } }; public RollViewPager(Context context, final List dotviewList, OnViewPagerItemClickListener onViewPagerItemClickListener) { super(context); this.context = context; this.onItemClickListener = onViewPagerItemClickListener; bitmapUtils = new BitmapUtils(context); this.setOnPageChangeListener(new OnPageChangeListener() { @Override public void onPageSelected(int arg0) { top_news_title.setText(titleList.get(arg0)); for (int i = 0; i < dotviewList.size(); i++) { if (arg0 == i) { dotviewList.get(i).setBackgroundResource(R.drawable.dot_focus); } else { dotviewList.get(i).setBackgroundResource(R.drawable.dot_normal); } } } @Override public void onPageScrolled(int arg0, float arg1, int arg2) { } @Override public void onPageScrollStateChanged(int arg0) { } }); this.setCurrentItem(currentItem); } @Override protected void onDetachedFromWindow() { super.onDetachedFromWindow(); handler.removeCallbacksAndMessages(null); } private int downX; private int downY; @Override public boolean dispatchTouchEvent(MotionEvent ev) { switch (ev.getAction()) { case MotionEvent.ACTION_DOWN: // 讓當前viewpager的父控制項不去攔截touch事件 getParent().requestDisallowInterceptTouchEvent(true); downX = (int) ev.getX(); downY = (int) ev.getY(); break; case MotionEvent.ACTION_MOVE: int moveX = (int) ev.getX(); int moveY = (int) ev.getY(); if (Math.abs(moveX - downX) >= Math.abs(moveY - downY)) { // 滑動輪播圖 getParent().requestDisallowInterceptTouchEvent(true); } else { // 重新整理listview getParent().requestDisallowInterceptTouchEvent(false); } break; } return super.dispatchTouchEvent(ev); } public void initTitleLists(TextView top_news_title, List titleList) { if (null != top_news_title && null != titleList && titleList.size() > 0) { top_news_title.setText(titleList.get(0)); } this.titleList = titleList; this.top_news_title = top_news_title; } public void initUrlImgList(List urlImgList) { this.urlImgList = urlImgList; LogUtil.d(TAG, "=====urlImgList size:"+urlImgList.size()); } /** * 滾動viewpager */ public void startRoll() { if (adapter == null) { adapter = new MyRollViewPagerAdapter(); this.setAdapter(adapter); } else { adapter.notifyDataSetChanged(); } handler.postDelayed(new Runnable() { @Override public void run() { currentItem = (currentItem + 1)%urlImgList.size(); handler.obtainMessage().sendToTarget(); } }, 3000); } class MyRollViewPagerAdapter extends PagerAdapter { @Override public int getCount() { return urlImgList.size(); } @Override public boolean isViewFromObject(View arg0, Object arg1) { return arg0 == arg1; } @Override public Object instantiateItem(ViewGroup container, final int position) { View view = View.inflate(context, R.layout.viewpager_item, null); ImageView imageView = (ImageView) view.findViewById(R.id.image); bitmapUtils.display(imageView, urlImgList.get(position)); view.setOnTouchListener(new OnTouchListener() { private int downX; private int downY; private long downTime; @Override public boolean onTouch(View v, MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: handler.removeCallbacksAndMessages(null); downX = (int)event.getX(); downY = (int)event.getY(); downTime = System.currentTimeMillis(); break; case MotionEvent.ACTION_MOVE: break; case MotionEvent.ACTION_UP: if (System.currentTimeMillis() - downTime < 500 && Math.abs(downX - event.getX()) < 5 && Math.abs(downY - event.getY()) < 5) { LogUtil.d(TAG, "=====imageView被點擊了, 跳轉到對應新聞內容頁面"); // 介面回調 if (onItemClickListener != null) { onItemClickListener.onClick(position); } } startRoll(); break; case MotionEvent.ACTION_CANCEL: startRoll(); break; } return true; } }); ((RollViewPager)container).addView(imageView); return imageView; } @Override public void destroyItem(ViewGroup container, int position, Object object) { ((RollViewPager)container).removeView((View) object); } } /** * viewpager 的 item 被點擊時 回調用的介面 * @author lenovo * */ public interface OnViewPagerItemClickListener { public void onClick(int i); }}

問題:
手指touch到輪播圖上時,暫停輪播。手動滑動到下一輪播圖後,程式不能自動輪播了

解決方案:

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.