Android之ViewPager实现图片无限循环轮播
来源:互联网 发布:编程兼职怎么赚钱 编辑:程序博客网 时间:2024/04/29 17:46
很久没有写博客了,之前花时间写了一个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" > <FrameLayout android:layout_width="match_parent" android:layout_height="130dp"> <android.support.v4.view.ViewPager android:id="@+id/main_picturecarousel_vp" android:layout_width="match_parent" android:layout_height="match_parent"> </android.support.v4.view.ViewPager> <LinearLayout android:layout_width="98dp" android:layout_height="7dp" android:orientation="horizontal" android:layout_marginBottom="10dp" android:layout_gravity="center_horizontal|bottom"> <ImageView android:id="@+id/picturecarousel_img0" android:layout_width="7dp" android:layout_height="7dp" android:src="@drawable/dian0" /> <ImageView android:id="@+id/picturecarousel_img1" android:layout_marginLeft="7dp" android:layout_width="7dp" android:layout_height="7dp" android:src="@drawable/dian1" /> <ImageView android:id="@+id/picturecarousel_img2" android:layout_marginLeft="7dp" android:layout_width="7dp" android:layout_height="7dp" android:src="@drawable/dian1" /> <ImageView android:id="@+id/picturecarousel_img3" android:layout_marginLeft="7dp" android:layout_width="7dp" android:layout_height="7dp" android:src="@drawable/dian1" /> <ImageView android:id="@+id/picturecarousel_img4" android:layout_marginLeft="7dp" android:layout_width="7dp" android:layout_height="7dp" android:src="@drawable/dian1" /> <ImageView android:id="@+id/picturecarousel_img5" android:layout_marginLeft="7dp" android:layout_width="7dp" android:layout_height="7dp" android:src="@drawable/dian1" /> <ImageView android: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 */ @Override public int getCount() { //设置成最大,使无限循环 return 10000; } @Override public boolean isViewFromObject(View view, Object object) { return view==object; } /** * 由于我们在instantiateItem()方法中已经处理了remove的逻辑, * 因此这里并不需要处理。实际上,实验表明这里如果加上了remove的调用, * 则会出现ViewPager的内容为空的情况。 * @param container * @param position * @param object */ @Override public void destroyItem(ViewGroup container, int position, Object object) { //警告:不要在这里调用removeView } /** * @param container * @param position * @return * 对position进行求模操作 * 因为当用户向左滑时position可能出现负值,所以必须进行处理 */ @Override public 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; } @Override public void handleMessage(Message msg) { super.handleMessage(msg); HomeFrag homeFrag = weakReference.get(); if (homeFrag == null) { //HomeFrag已经回收,无需继续处理UI return; } //检查消息队列并移除未发送的消息,这主要是避免在复杂环境下消息出现重复等问题。 /** * 这段会把第一次的自动轮播事件吃掉,所以可以加个条件,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() { @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { } @Override public void onPageSelected(int position) { showpoint(position); handler.sendMessage(Message.obtain(handler, ImageCarouseHandler.MSG_PAGE_CHANGED, position, 0)); } //覆写该方法实现轮播效果 @Override public 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:宋体;"> @Override public void onPageSelected(int position) { showpoint(position); handler.sendMessage(Message.obtain(handler, ImageCarouseHandler.MSG_PAGE_CHANGED, position, 0)); }</span>
QAQ上次写博客已经过去很久了,下次也不知道是什么时候。。。事情太多,生活太复杂╮(╯▽╰)╭
想买好多书QAQ。。。但是好穷。。╮(╯▽╰)╭
6 2
- Android之ViewPager实现图片无限循环轮播
- Android viewpager实现无限循环轮播
- Android ViewPager从网络获取图片实现无限轮播
- ViewPager实现图片的自动轮播和无限循环
- Android ViewPager实现广告无限轮播
- Android 无限轮播ViewPager的实现
- ImageView实现图片的无限轮播 以及viewpager实现图片的无限轮播
- 使用ViewPager实现自动无限循环的轮播
- ViewPager实现广告轮播---(一)(无限循环)
- ViewPager实现无限循环轮播控件的核心要点
- Android中可无限循环轮播的ViewPager
- Android使用ViewPager实现无限循环滑动及轮播(附源码)
- ViewPager实现无限轮播
- ViewPager无限轮播实现
- 使用Viewpager Indicator实现图片无限轮播
- ViewPager网络加载图片并无限轮播实现
- ViewPager实现图片无限轮播(上)
- ViewPager实现图片无限轮播(下)
- 第4周 C语言及程序设计提高例程-9 函数的嵌套调用
- mybatis做insert操作的时候 怎么才能返回插入的那条数据的id?
- http、TCP/IP协议与socket之间的区别
- 介绍一个开源的SIP(VOIP)协议库PJSIP
- 病毒木马查杀实战第022篇:txt病毒研究
- Android之ViewPager实现图片无限循环轮播
- 《跟着小吴哥学python》之 05 python中的集合 dict&set
- 雷锋依然在人间—工厂方法模式
- Android属性动画Interpolator(插值器)
- getchar()和getch()的区别
- 把assets目录下的db文件拷贝进来
- jsp传list到spring mvc
- 极光推送简单解析
- 使用 Google Guava 美化你的 Java 代码