Android图片循环轮播控件原理

图片轮播控件通常由ViewPager和指示器组成。
因为ViewPager并不支持循环翻页,需要自己去处理。当ViewPager在第一项和最后一项时不能向前或向后滑动,那我们可以在原列表首尾各增加一项。增加首项为原列表的最后一项,尾项为原列表的第一项。并在ViewPager切换到边界页时,静默地更改到第二页或倒数第二页,就可以循环滚动切换了。使用了ViewPage.setCurrentItem(int item, boolean smoothScroll) 立即切换页面。

索引位置 原列表 ViewPager展示列表
0 A B
1 B A
2 B
3 A

主要代码:

 //轮播图数量
 private int count;
 //ViewPager当前项
 private int mCurrentItem;

private void setImageList(List imageUrls) {
       ...
       for (int i = 0; i <= count + 1; i ++) {
           ...
           Object path;
           if (i == 0) {
               path = imageUrls.get(count - 1);
           } else if (i == count + 1) {
               path = imageUrls.get(0);
           } else {
               path = imageUrls.get(i - 1);
           }
           ...
       }
   }

/**
* 监听ViewPager滚动状态
*/
@Override
 public void onPageScrollStateChanged(int state) {
     Log.i(tag, "onPageScrollStateChanged state=" + state);
     if (mOnPageChangeListener != null) {
         mOnPageChangeListener.onPageScrollStateChanged(state);
     }
     switch (state) {
         case ViewPager.SCROLL_STATE_IDLE://无操作
             setCurrentPageSilence();
             break;
         case ViewPager.SCROLL_STATE_DRAGGING://开始拖动
             setCurrentPageSilence();
             break;
         case ViewPager.SCROLL_STATE_SETTLING://拖动最终位置
             break;
     }
 }

/**
  * 静静地切换页面
  */
  private void setCurrentPageSilence() {
      if (mCurrentItem == 0) {
          mViewPager.setCurrentItem(count, false);
      } else if(mCurrentItem == count + 1) {
          mViewPager.setCurrentItem(1, false);
      }
  }

此外自动轮播是通过Handler提交延时任务来实现的,运行任务时切换到下一页。同样在轮播到最后一页时静默地更改到第二页。

/**
     * 向后轮播任务
     */
    private Runnable mPlayTask = new Runnable() {
        @Override
        public void run() {
            if (mIsAutoPlay) {
                if (mCurrentItem == count + 1) {
                    mCurrentItem = 1;
                    setCurrentPageSilence();
                    mHandler.post(this);
                } else {
                    mCurrentItem += 1;
                    //下一页
                    mViewPager.setCurrentItem(mCurrentItem);
                    mHandler.postDelayed(this, mDelayTime);
                }
            }
        }
    };

这里要注意Handler引用没释放导致内存泄漏的问题。

你可能感兴趣的:(自定义控件,轮播图,andorid)