今天看啥
热点:

Android——ViewPager和内部view之间的事件分发及轮播图,androidviewpager


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接管。

总结:
前提:内部view的setOnTouchListener的onTouch()方法返回true。(表示该View内部消化掉了所有事件)
滑动viewpager去切换不同的item时:
当滑动的距离没有达到临界值(通常viewpager还在当前item),事件会一直作用在内部的view身上,
当滑动的距离(像素点)达到一定阀值(临界值)时(通常viewpager已滑到下一个item),会触发内部view的ACTION_CANCEL事件。后续的ACTION_MOVE、ACTION_UP都被viewpager接管,作用在外面的viewpager身上。

三、案例
图片轮播效果图:
这里写图片描述
自定义轮播图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<String> titleList;
    private List<String> 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<View> 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<String> 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<String> 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到轮播图上时,暂停轮播。手动滑动到下一轮播图后,程序不能自动轮播了
这里写图片描述

解决方法:
这里写图片描述

www.bkjia.comtruehttp://www.bkjia.com/Androidjc/1021422.htmlTechArticleAndroid——ViewPager和内部view之间的事件分发及轮播图,androidviewpager viewpager 在滑动的过程中是如何触发view身上的事件的,换句话说,viewpa...

相关文章

帮客评论

视觉看点