android ViewPager实现自动无限轮播和下方向导圆点
程序员文章站
2023-12-18 14:23:04
一、布局
小圆点形状的生成shape.xml文件
使用空心还是实心的把对应的注释去掉就可以了.
一、布局
小圆点形状的生成shape.xml文件
使用空心还是实心的把对应的注释去掉就可以了.
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval" android:uselevel="false"> <!-- 实心圆 <solid android:color="#f00"/> --> <!-- 空心圆 <stroke android:width="1dp" android:color="@android:color/black"/> --> <size android:width="8dp" android:height="8dp"/> </shape>
轮播的viewpager和向导圆点的 布局文件xml
<?xml version="1.0" encoding="utf-8"?> <relativelayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="200dp"> <android.support.v4.view.viewpager xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/hometab_vp" android:layout_width="match_parent" android:layout_height="200dp"> </android.support.v4.view.viewpager> <relativelayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignparentbottom="true" android:layout_centerhorizontal="true" android:layout_marginbottom="20dp" > <linearlayout android:id="@+id/ll_dot" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal"> <imageview android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/shape_guide_dot_default"/> <imageview android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginleft="5dp" android:src="@drawable/shape_guide_dot_default"/> <imageview android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginleft="5dp" android:src="@drawable/shape_guide_dot_default"/> <imageview android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginleft="5dp" android:src="@drawable/shape_guide_dot_default"/> <imageview android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginleft="5dp" android:src="@drawable/shape_guide_dot_default"/> </linearlayout> <imageview android:id="@+id/dot_red" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/shape_guide_dot_solid"/> </relativelayout> </relativelayout>
二,代码
左右轮播的viewpager的adapter
/** * 轮播 viewpager的adapter */ class mylooppageradapter extends pageradapter { private int[] welcomes; private context mcontext; public mylooppageradapter(int[] welcomes, context context) { this.welcomes = welcomes; mcontext = context; } // //返回实际要显示的图片数+2 @override public int getcount() { return welcomes.length + 2; } @override public boolean isviewfromobject(view view, object object) { return view == object; } @override public object instantiateitem(viewgroup container, int position) { imageview iv = new imageview(mcontext); int realposition = (position - 1 + welcomes.length) % welcomes.length; // 设置背景图片 iv.setbackgroundresource(welcomes[realposition]); container.addview(iv); return iv; } @override public void destroyitem(viewgroup container, int position, object object) { //注意不要remove 否则容易闪屏 // container.removeview((imageview) object); } }
添加viewpager的addonpagechangelistener
/** * 循环轮播界面change的 监听器 */ class mylooppagechangelistener implements viewpager.onpagechangelistener { private viewpager mviewpager; private linearlayout mlldot; private imageview dotred; private handler mhandler; private runnable mrunnable; /** * 初始化 控件 和 handler * * @param viewpager * @param lldot * @param dotred */ public mylooppagechangelistener(viewpager viewpager, linearlayout lldot, imageview dotred) { mviewpager = viewpager; this.mlldot = lldot; this.dotred = dotred; initautoloop(); } /** * 初始化 自动轮播 handler 和 runnable */ private void initautoloop() { mhandler = new handler() { @override public void handlemessage(message msg) { // logutils.e("have received a msg"); int curindex = (mviewpager.getcurrentitem() + 1) % (welcomes.length + 2); mviewpager.setcurrentitem(curindex, true); } }; mrunnable = new runnable() { @override public void run() { message message = new message(); mhandler.sendmessage(message); } }; // 开始 轮播 mhandler.postdelayed(mrunnable, 3 * 1000); } /** * 当页面在滑动了调用 * * @param position 当前页面,即点击滑动的页面 * @param positionoffset 当前页面偏移的百分比 * @param positionoffsetpixels 当前页面偏移的像素位置 */ @override public void onpagescrolled(int position, float positionoffset, int positionoffsetpixels) { // 获取到 真正图片所在的位置. int realposition = (position - 1 + welcomes.length) % welcomes.length; // 获取到红点 的 layout 参数 relativelayout.layoutparams params = (relativelayout.layoutparams) dotred.getlayoutparams(); // 计算两个点之间的距离 int dotdis = mlldot.getchildat(1).getleft() - mlldot.getchildat(0).getleft(); // 计算总共的左边距 int totalleftmargin = (welcomes.length - 1) * dotdis; // 计算滑动的距离 float dis = realposition * dotdis + positionoffset * dotdis; // 设置 margin_left 的值, // 如果 position 等于 0 说明正在从第一个图片想最后一个滑动,那么保持 向导的状态为不动 if (position == 0) { params.leftmargin = 0; // 如果滑动距离超过了 最大边距,那么将最大边距赋值给 红点的参数左边距 } else if (dis > totalleftmargin) { params.leftmargin = totalleftmargin; // 正常情况 就将滑动的距离 直接赋值 } else { params.leftmargin = (int) dis; } // 设置红点的 参数 dotred.setlayoutparams(params); // 在position4左滑且左滑positionoffset百分比接近1时,偷偷替换为position1(原本会滑到position5) if (position == welcomes.length && positionoffset > 0.99) { mviewpager.setcurrentitem(1, false); // 在position1右滑且右滑百分比接近0时,偷偷替换为position4(原本会滑到position0) } else if (position == 0 && positionoffset < 0.01) { mviewpager.setcurrentitem(welcomes.length, false); } } @override public void onpageselected(int position) { } @override public void onpagescrollstatechanged(int state) { switch (state) { case 0://什么都没做 空闲状态 break; case 1://正在滑动: // 手动滑动 取消自动滑动 mhandler.removecallbacks(mrunnable); break; case 2://滑动完毕: // 继续 自动滑动 mhandler.postdelayed(mrunnable, 3 * 1000); break; } } }
// 主要的算法参考下图 int realposition = (position - 1 + welcomes.length) % welcomes.length;
由下图可以发现,应该初始化viewpager.setcurrentitem(1);才能从预设的第一页开始播放。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。