使用ViewPager实现左右循环滑动及轮播效果

来源:互联网 发布:cinebench数据库 编辑:程序博客网 时间:2024/05/16 10:30

吃水不忘挖井人:

本文修改自博客:http://www.cnblogs.com/kobe8/p/4343478.html


读了上文感觉思路挺不错的,但是实践的时候发现了一些问题。比如,打开应用时banner并没有自动开始轮播,因为handler中的if判断把消息给吃掉了。

由此,我感觉这种处理方式并不是很好,出现重复发消息的问题,又通过其它方式来删除掉这些消息。。。

我对代码做了一下修改:

1、删除掉了以下这两种消息的定义,改为在viewpager的监听器中关闭和重发更新banner的消息。

 /**
         * 请求暂停轮播。
         */
        protected static final int MSG_KEEP_SILENT   = 2;
        /**
         * 请求恢复轮播。
         */
        protected static final int MSG_BREAK_SILENT  = 3;

2、 为了防止用户手指长时间停留在banner上,出现的轮动bug。增加了一个flag。


修改后的各部分源码如下:

1、pageradapter

public 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;    }}

2、ImageHandler


public class ImageHandler extends Handler {    /**     * 请求更新显示的View。     */    public static final int MSG_UPDATE_IMAGE  = 1;    /**     * 记录最新的页号,当用户手动滑动时需要记录新页号,否则会使轮播的页面出错。     * 例如当前如果在第一页,本来准备播放的是第二页,而这时候用户滑动到了末页,     * 则应该播放的是第一页,如果继续按照原来的第二页播放,则逻辑上有问题。     */    public static final int MSG_PAGE_CHANGED  = 4;    //轮播间隔时间    public static final long MSG_DELAY = 3000;    //使用弱引用避免Handler泄露.这里的泛型参数可以不是Activity,也可以是Fragment等    private WeakReference<MainActivity> weakReference;    private int currentItem = 0;    private String LOG_TAG="ImageHandler";    public ImageHandler(WeakReference<MainActivity> wk){        weakReference = wk;    }    @Override    public void handleMessage(Message msg) {        super.handleMessage(msg);        Log.d(LOG_TAG," receive message " + msg.what);        MainActivity activity = weakReference.get();        if (activity==null){            //Activity已经回收,无需再处理UI了            return ;        }        switch (msg.what) {            case MSG_UPDATE_IMAGE:                currentItem++;                activity.viewPager.setCurrentItem(currentItem);                //准备下次播放                activity.handler.sendEmptyMessageDelayed(MSG_UPDATE_IMAGE, MSG_DELAY);                break;            case MSG_PAGE_CHANGED:                //记录当前的页号,避免播放的时候页面显示不正确。                currentItem = msg.arg1;                break;            default:                break;        }    }}


3、主Activity中使用viewpager的代码


public class MainActivity extends Activity {    private static final String LOG_TAG = "MainActivity";    public  ImageHandler handler = new ImageHandler(new WeakReference<MainActivity>(this));    public ViewPager viewPager;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        //初始化iewPager的内容        viewPager = (ViewPager) findViewById(R.id.main_viewpager);        LayoutInflater inflater = LayoutInflater.from(this);        ImageView view1 = (ImageView) inflater.inflate(R.layout.item, null);        ImageView view2 = (ImageView) inflater.inflate(R.layout.item, null);        ImageView view3 = (ImageView) inflater.inflate(R.layout.item, null);        view1.setImageResource(R.drawable.a1);        view2.setImageResource(R.drawable.a2);        view3.setImageResource(R.drawable.a3);        ArrayList<ImageView> views = new ArrayList<ImageView>();        views.add(view1);        views.add(view2);        views.add(view3);        viewPager.setAdapter(new ImageAdapter(views));        viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {            Boolean flag=false;//标识用户是否滑动了banner,即ViewPager.SCROLL_STATE_DRAGGING是否发生了。            //配合Adapter的currentItem字段进行设置。            @Override            public void onPageSelected(int arg0) {                Log.d("MainActivity","-----------currentItem is "+arg0);                handler.sendMessage(Message.obtain(handler, ImageHandler.MSG_PAGE_CHANGED, arg0, 0));            }            @Override            public void onPageScrolled(int arg0, float arg1, int arg2) {            }            //覆写该方法实现轮播效果的暂停和恢复            @Override            public void onPageScrollStateChanged(int arg0) {                switch (arg0) {                    case ViewPager.SCROLL_STATE_DRAGGING:                        flag=true;                        if (handler.hasMessages(ImageHandler.MSG_UPDATE_IMAGE)){                            Log.d(LOG_TAG,"-------------------------------------- 用户滑动了banner,暂停轮播 " );                            handler.removeMessages(ImageHandler.MSG_UPDATE_IMAGE);                        }                        break;                    case ViewPager.SCROLL_STATE_IDLE:                        if (flag){                            flag=false;                            Log.d(LOG_TAG,"-------------------------------------- 重新开启轮播 " );                            handler.sendEmptyMessageDelayed(ImageHandler.MSG_UPDATE_IMAGE, ImageHandler.MSG_DELAY);                        }                        break;                    default:                        break;                }            }        });        viewPager.setCurrentItem(Integer.MAX_VALUE/2);//默认在中间,使用户看不到边界        //开始轮播效果        handler.sendEmptyMessageDelayed(ImageHandler.MSG_UPDATE_IMAGE, ImageHandler.MSG_DELAY);    }//end of onCreate}//end of MainActivity


至于activity的布局文件以及R.layout.item,就不列出来了。

activity中是个viewpager

item中是个ImageView


0 0
原创粉丝点击