很久没有写博客了,之前花时间写了一个Viewpager实现的无限图片轮播,个人感觉还是很好用的QAQ,源码和思路都还算清晰

实现的效果图如下:

这里要补充一下,在这个项目中我把图片轮播写进了一个Viewholder里内嵌在了Recyclelistview里。但本文只介绍图片轮播部分的实现:

整体思路:使用handler的延时发送方法(sendEmptyMessageDelayed)实现在adapter中控制Viewpager图片轮播

具体实现分为三个部分:

首先是轮播图片的布局文件main_home_picturecarousel.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="130dp"android:orientation="vertical"><FrameLayoutandroid:layout_width="match_parent"android:layout_height="130dp"><android.support.v4.view.ViewPagerandroid:id="@+id/main_picturecarousel_vp"android:layout_width="match_parent"android:layout_height="match_parent"></android.support.v4.view.ViewPager><LinearLayoutandroid:layout_width="98dp"android:layout_height="7dp"android:orientation="horizontal"android:layout_marginBottom="10dp"android:layout_gravity="center_horizontal|bottom"><ImageViewandroid:id="@+id/picturecarousel_img0"android:layout_width="7dp"android:layout_height="7dp"android:src="@drawable/dian0"/><ImageViewandroid:id="@+id/picturecarousel_img1"android:layout_marginLeft="7dp"android:layout_width="7dp"android:layout_height="7dp"android:src="@drawable/dian1"/><ImageViewandroid:id="@+id/picturecarousel_img2"android:layout_marginLeft="7dp"android:layout_width="7dp"android:layout_height="7dp"android:src="@drawable/dian1"/><ImageViewandroid:id="@+id/picturecarousel_img3"android:layout_marginLeft="7dp"android:layout_width="7dp"android:layout_height="7dp"android:src="@drawable/dian1"/><ImageViewandroid:id="@+id/picturecarousel_img4"android:layout_marginLeft="7dp"android:layout_width="7dp"android:layout_height="7dp"android:src="@drawable/dian1"/><ImageViewandroid:id="@+id/picturecarousel_img5"android:layout_marginLeft="7dp"android:layout_width="7dp"android:layout_height="7dp"android:src="@drawable/dian1"/><ImageViewandroid:id="@+id/picturecarousel_img6"android:layout_marginLeft="7dp"android:layout_width="7dp"android:layout_height="7dp"android:src="@drawable/dian1"/></LinearLayout></FrameLayout>
</LinearLayout>

Step1:ViewPager实现部分:

Viewpager需要绑定一个PagerAdapter,所以首先需要自定义一个PagerAdapter:

public class ImageAdapter extends PagerAdapter {private Context context;//轮播需要的图片public ArrayList<ImageView> imgs;public ImageAdapter(Context context, ArrayList<ImageView> imgs) {this.context = context;this.imgs = imgs;}/*** ViewPager的边界* @return*/@Overridepublic int getCount() {//设置成最大,使无限循环return 10000;}@Overridepublic boolean isViewFromObject(View view, Object object) {return view==object;}/*** 由于我们在instantiateItem()方法中已经处理了remove的逻辑,* 因此这里并不需要处理。实际上,实验表明这里如果加上了remove的调用,* 则会出现ViewPager的内容为空的情况。* @param container* @param position* @param object*/@Overridepublic void destroyItem(ViewGroup container, int position, Object object) {//警告:不要在这里调用removeView}/*** @param container* @param position* @return* 对position进行求模操作* 因为当用户向左滑时position可能出现负值,所以必须进行处理*/@Overridepublic Object instantiateItem(ViewGroup container, int position) {//对Viewpager页号求模去除View列表中要显示的项position %= imgs.size();if (position<0) {position = imgs.size() + position;}ImageView view = imgs.get(position);//如果View已经在之前添加到了一个父组件,则必须先remove,否则会抛出IllegalStateException。ViewParent viewParent = view.getParent();if (viewParent!=null){ViewGroup parent = (ViewGroup)viewParent;parent.removeView(view);}container.addView(view);return view;}
}

这里需要注意几个方面:1、最大值设置:可以设置为Interger.MAXVALUE实现无限(不过我觉得1W已经很多了。。)

2、instantiateItem方法中的页号显示逻辑处理部分,这里要考虑如果一开始位置设置为0往左滑会出现position为负值的情况

3、轮播之后View的移除

Step2:Handler实现计时轮播部分:

这里需要实现一个自定义的图片轮播用到的handler:

public class ImageCarouseHandler extends Handler {/*** 请求更新显示的View*/public static final int MSG_UPDATE_IMAGE = 1;/*** 请求暂停轮播*/public static final int MSG_KEEP_SILENT   = 2;/*** 请求恢复轮播。*/public static final int MSG_BREAK_SILENT  = 3;/*** 记录最新的页号,当用户手动滑动时需要记录新页号,否则会使轮播的页面出错。* 例如当前如果在第一页,本来准备播放的是第二页,而这时候用户滑动到了末页,* 则应该播放的是第一页,如果继续按照原来的第二页播放,则逻辑上有问题。*/public static final int MSG_PAGE_CHANGED  = 4;//轮播间隔时间public static final long MSG_DELAY = 3000;//这里使用弱引用避免Handler泄露private WeakReference<HomeFrag> weakReference;private int currentItem = Integer.MAX_VALUE/2;public ImageCarouseHandler(WeakReference<HomeFrag> wk) {weakReference = wk;}@Overridepublic void handleMessage(Message msg) {super.handleMessage(msg);HomeFrag homeFrag = weakReference.get();if (homeFrag == null) {//HomeFrag已经回收,无需继续处理UIreturn;}//检查消息队列并移除未发送的消息,这主要是避免在复杂环境下消息出现重复等问题。/*** 这段会把第一次的自动轮播事件吃掉,所以可以加个条件,Position!=Max/2的时候才清除事件.因为第一次Position一定等于Max/2*/if ((  homeFrag.handler.hasMessages(MSG_UPDATE_IMAGE))&&(currentItem!=Integer.MAX_VALUE/2)){homeFrag.handler.removeMessages(MSG_UPDATE_IMAGE);}switch (msg.what) {case MSG_UPDATE_IMAGE:currentItem++;homeFrag.ChanggeViewPagerCurrentItem(currentItem);//准备下次播放homeFrag.handler.sendEmptyMessageDelayed(MSG_UPDATE_IMAGE, MSG_DELAY);break;case MSG_KEEP_SILENT://只要不发送消息就暂停了break;case MSG_BREAK_SILENT:homeFrag.handler.sendEmptyMessageDelayed(MSG_UPDATE_IMAGE, MSG_DELAY);break;case MSG_PAGE_CHANGED://记录当前的页号,避免播放的时候页面显示不正确。currentItem = msg.arg1;break;default:break;}}
}

这里要注意设置不同状态的几种情况,以及要特别注意用户进行拖拽操作时要考虑到轮播暂停和拖拽事件结束后的恢复轮播的问题。

最后就是具体在内容中的代码实现部分了:

            View view = LayoutInflater.from(context).inflate(R.layout.main_home_picturecarousel,null);vp = (ViewPager) view.findViewById(R.id.main_picturecarousel_vp);views = new ArrayList<>();LayoutInflater inflater = LayoutInflater.from(context);for (int i = 0;i<7; i++) {ImageView imgv = (ImageView) inflater.inflate(R.layout.picturecarouse_item,null);imgv.setImageResource(imgres[i]);views.add(imgv);//初始化点点pointimgs[i] = (ImageView) view.findViewById(pointimgsres[i]);}vp.setAdapter(new ImageAdapter(context,views));
    vp.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {@Overridepublic void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {}@Overridepublic void onPageSelected(int position) {showpoint(position);handler.sendMessage(Message.obtain(handler, ImageCarouseHandler.MSG_PAGE_CHANGED, position, 0));}//覆写该方法实现轮播效果@Overridepublic void onPageScrollStateChanged(int state) {switch (state) {case ViewPager.SCROLL_STATE_DRAGGING:handler.sendEmptyMessage(ImageCarouseHandler.MSG_KEEP_SILENT);break;case ViewPager.SCROLL_STATE_IDLE:handler.sendEmptyMessageDelayed(ImageCarouseHandler.MSG_UPDATE_IMAGE, ImageCarouseHandler.MSG_DELAY);break;default:break;}}});vp.setCurrentItem(4998);//开始轮播效果handler.sendEmptyMessageDelayed(ImageCarouseHandler.MSG_UPDATE_IMAGE, ImageCarouseHandler.MSG_DELAY);//注意,设置Page 即缓存页面的个数,数过小时会出现fragment重复加载的问题

Step3:小圆点实现:

在布局文件中已经布置过小圆点的位置了,所以这里只要实现一个改变小圆点状态的方法:

<span style="font-family:宋体;">    private void showpoint(int position) {//dian0-白色 dian1-灰色for (int i = 0;i<7;i++) {pointimgs[i].setImageResource(R.drawable.dian1);pointimgs[position%7].setImageResource(R.drawable.dian0);}}</span>

然后在viewpager的onPageSelected()方法中调用:

<span style="font-family:宋体;">            @Overridepublic void onPageSelected(int position) {showpoint(position);handler.sendMessage(Message.obtain(handler, ImageCarouseHandler.MSG_PAGE_CHANGED, position, 0));}</span>

QAQ上次写博客已经过去很久了,下次也不知道是什么时候。。。事情太多,生活太复杂╮(╯▽╰)╭

想买好多书QAQ。。。但是好穷。。╮(╯▽╰)╭

Android之ViewPager实现图片无限循环轮播相关推荐

  1. 利用jQuery实现图片无限循环轮播(不借助于轮播插件)

    原来我主要是用Bootstrap框架或者swiper插件实现轮播图的功能,而这次是用jQuery来实现图片无限循环轮播! 用到的技术有:html.css.JavaScript(少).jQuery(主要 ...

  2. html图片自动循环轮播图,js实现图片无缝循环轮播

    本文实例为大家分享了js实现图片无缝循环轮播的具体代码,供大家参考,具体内容如下 代码如下 Document #container{ overflow:hidden; width:400px; hei ...

  3. html5图片无限循环播放,原生js实现无限循环轮播图效果

    知识要点 1.实现无限循环的原理: 以偏移的距离来判断是否跳回第一张和最后一张 也可以利用循环判断图片的当前索引值 var newLeft=parseInt(list.style.left)+offs ...

  4. 一种无限循环轮播图的实现原理

    本文来自 http://www.jianshu.com/p/ef03ec7f23b2 轮播实现步骤 接下来,笔者将从各方面逐一分析 层级结构 最底层是一个UIView,上面有一个UIScrollVie ...

  5. Android之自定义ViewPager实现图片的无线轮播

    PS:以前也写过关于图片轮播这一块的博客.不过写的很烂,并且很多情况没有考虑到(没有支持无线轮播,和手势点击事件).因此这里写一篇补上.也是当时太年轻了. 注:图片请放大后再看.否则看不清楚. 学习内 ...

  6. android 3d布局轮播,android 图片/视频混合轮播控件banner

    android 图片/视频混合轮播控件banner 在youth5201314的图片轮播控件做的修改 原作者github地址:https://github.com/youth5201314/banne ...

  7. JQuery图片无限循环滚动源码

    平常项目中经常用到图片循环滚动,所以就写些必要的CSS定位,JS基本算法,最后就封装成JQuery图片无限循环滚动插件类,其实本质上是li块无限循环滚动,li块里面不管是图片还是其它内容,都OK的. ...

  8. 简单的图片、文字轮播,及切换动画

    图片轮播使用的容器是ViewPager,文字轮播使用的是TextSwitcher. 图片轮播的主要思路:利用Timer和TimerTask构建定时任务:监听ViewPager的滑动,根据滑动百分比动态 ...

  9. css+js制作循环轮播图——可滑动

    先上效果图: (1)自动切换 (2)手动拖拽 HTML <div id="adbox" class="adbar"><img src=&quo ...

最新文章

  1. FFmpeg--av_register_all函数分析
  2. 板邓:【WordPress文件解读】wp-config.php
  3. Adobe illustrator 多个对象进行环形布局 - 连载22
  4. 百度编辑器的初步使用
  5. Unix Vi 命令详解
  6. AI人才有多贵?年薪三五十万美元起步,高校教授大量投身工业界
  7. 《奠基计算机网络》所需软件 下载地址
  8. 大数据项目实战-电商日志平台
  9. JMeter自动生成测试Report
  10. 【Python】利用MD5文件去重
  11. 记录xmapp升级过程中解决mysql扩展中出现的问题
  12. word批量替换向下箭头为回车符号、批量删除空行、批量空格与空行
  13. linux kernel配置调试方法
  14. 文件上传与下载之数据库实现
  15. xp怎么删除计算机管理员用户名和密码,Windows XP 的 Administrator 超级管理员密码忘记了,如何清除?...
  16. 微服务项目:尚融宝(42)(核心业务流程:借款额度审批(2))
  17. 一次有趣的 DNS 导致 Node 服务故障问题分析实录
  18. C语言学习之认识exit()函数
  19. YOJ3509-小豪搬宝藏
  20. 音视频互动平台应用分析

热门文章

  1. 迷雾世界无限号服务器,迷雾世界盘底现存的服务器 合服潮涌现
  2. 计算机作业微波炉工作的原理,微波炉的工作原理和原理图解析
  3. mac 下用FFMpeg推流,(直播)
  4. macOS多显示屏时将程序坞和启动台移动到另一个屏幕下
  5. Sort using
  6. Navicat Cannot conect to MySQL server 10060
  7. 图解数据分析(3) | 数据分析的数学基础(数据科学家入门·完结)
  8. 游戏盾的防御原理及产品特性
  9. 四旋翼无人机调试时,电机滴滴滴响问题及解决办法汇总
  10. 如何判断目标主机是否在监听一个UDP端口(阿里云二面)