欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

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);才能从预设的第一页开始播放。

android ViewPager实现自动无限轮播和下方向导圆点

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

上一篇:

下一篇: