Android实现带指示点的自动轮播无限循环效果

Android实现带指示点的自动轮播无限循环效果,第1张

概述想要实现无限轮播,一直向左滑动,当到最后一个view时,会滑动到第一个,无限…

想要实现无限轮播,一直向左滑动,当到最后一个vIEw时,会滑动到第一个,无限…

可以自己写VIEwPager然后加handler先实现自动滚动,当然这里我为了项目的进度直接使用了Trinea的AndroID-auto-scroll-vIEw-pager库,网址:点击进入github 引用库compile('cn.trinea.androID.vIEw.autoscrollvIEwpager:androID-auto-scroll-vIEw-pager:1.1.2') {
exclude module: 'support-v4'
之后

1布局为

<relativeLayout androID:layout_wIDth="match_parent" androID:layout_height="@dimen/y150"> <cn.trinea.androID.vIEw.autoscrollvIEwpager.autoScrollVIEwPager androID:ID="@+ID/vIEwpager1" androID:layout_wIDth="match_parent" androID:layout_height="wrap_content" /> <!--点点的布局--> <linearLayout androID:ID="@+ID/ll_dot1" androID:layout_wIDth="match_parent" androID:layout_height="wrap_content" androID:layout_alignParentBottom="true" androID:layout_marginBottom="8dp" androID:gravity="center" androID:orIEntation="horizontal" /> </relativeLayout> 

2 构建PagerAdapter
继承自RecyclingPagerAdapter (后面会贴出来源码)

 `public class Indicator1Adapter extends RecyclingPagerAdapter { private List<Integer> imageIDList; Context context; //是否循环(创造构造方法,在activity里设置是否) //集合大小 private int size; public Indicator1Adapter(List<Integer> mData,Context context) {  this.imageIDList = mData;  this.context = context;  this.size = mData.size();  isInfiniteLoop = false; } @OverrIDe public int getCount() { //是:最大(让集合的长度无限,从而模拟无限循环) 否,集合长度  return isInfiniteLoop ? Integer.MAX_VALUE : imageIDList.size(); } /**  * @return the isInfiniteLoop  */ public boolean isInfiniteLoop() {  return isInfiniteLoop; } /**  * @param是否无限循环  */ public Indicator1Adapter setInfiniteLoop(boolean isInfiniteLoop) {  this.isInfiniteLoop = isInfiniteLoop;  return this; } /**  * 真实的position  *  * @param position  * @return  */ private int getposition(int position) {  return isInfiniteLoop ? position % size : position; } @OverrIDe public VIEw getVIEw(int position,VIEw vIEw,VIEwGroup container) {  VIEwHolder holder;  if (vIEw == null) {   holder = new VIEwHolder();   vIEw = holder.imageVIEw = new ImageVIEw(context);   vIEw.setTag(holder);  } else {   holder = (VIEwHolder)vIEw.getTag();  }  holder.imageVIEw.setimageResource(imageIDList.get(getposition(position)));  holder.imageVIEw.setScaleType(ImageVIEw.ScaleType.FIT_XY);  return vIEw; } private static class VIEwHolder {  ImageVIEw imageVIEw; }}

3 在activity里或者fragment里就可以设置VIEwPager

定义的成员变量:

//vIEwpager1 @BindVIEw(R.ID.vIEwpager1) autoScrollVIEwPager mPager1; //承载小点点的控件容器(布局里有) @BindVIEw(R.ID.ll_dot1) linearLayout mLlDot1;
Indicator1Adapter adapter1 = new Indicator1Adapter( mData,act).setInfiniteLoop(true);//开启无限循环  mPager1.setAdapter(adapter1);  mPager1.setInterval(PLAY_TIME);//轮播时间间隔  mPager1.startautoScroll();//开启自动轮播  mPager1.setCurrentItem(Integer.MAX_VALUE / 2 - Integer.MAX_VALUE / 2 % mData.size());

然后你嫌弃官方的换图间隔时间太短,一闪而过,可以通过反射 设置

//通过反射让滚动速度为自己的喜好的(这里设为1.2s)  try {   FIEld fIEld = VIEwPager.class.getDeclaredFIEld("mScroller");   fIEld.setAccessible(true);   FixedSpeedScroller scroller = new FixedSpeedScroller(mPager1.getContext(),new AccelerateInterpolator());   fIEld.set(mPager1,scroller);   scroller.setmDuration(1200);  } catch (Exception e) {   Log.e(TAG,"Exception",e);  }

4 然后我们的小点点还没有使用呢
这里我写了方法:

/** * 设置状态点1 */ private voID setovalLayout1() {  for (int i = 0; i < mData.size(); i++) {  /**   * 生成对应数量的点点(布局,结果提供)   */   mLlDot1.addVIEw(inflater.inflate(R.layout.dot,null));  }  // 默认显示第一页  mLlDot1.getChildAt(0).findVIEwByID(R.ID.v_dot)    .setBackgroundResource(R.drawable.dot_selected);  mPager1.addOnPagechangelistener(new VIEwPager.OnPagechangelistener() {   public voID onPageSelected(int position) {    //遍历图片数组//    Toast.makeText(act,"position"+position,Toast.LENGTH_SHORT).show();    for (int i = 0; i < mData.size(); i++) {     if(i==position%mData.size()){      // 圆点选中      /**      * 这里需要注意如果直接写position,由于我们是无限循环,他的position是无限往上      *增加的,那么就会报空指针,因为我们总共才生成了mData.size()个点点,这里可以让当前的      *position取余,得到的即是当前位置的点点      */      mLlDot1.getChildAt(position%mData.size())        .findVIEwByID(R.ID.v_dot)        .setBackgroundResource(R.drawable.dot_selected);     }else{      // 取消圆点选中      mLlDot1.getChildAt(curIndex1%mData.size())        .findVIEwByID(R.ID.v_dot)        .setBackgroundResource(R.drawable.dot_normal);     }    }    curIndex1 = position;   }   public voID onPageScrolled(int arg0,float arg1,int arg2) {   }   public voID onPageScrollStateChanged(int arg0) {   }  }); }

别忘了重写

 @OverrIDe public voID onPause() {  super.onPause();  // stop auto scroll when onPause  mPager1.stopautoScroll(); } @OverrIDe public voID onResume() {  super.onResume();  // start auto scroll when onResume  mPager1.startautoScroll(); }

好了,无限循环自动轮播,完成了.

5点点布局:

<relativeLayout xmlns:androID="http://schemas.androID.com/apk/res/androID" androID:layout_wIDth="wrap_content" androID:layout_height="wrap_content"> <!-- 小圆点VIEw --> <VIEw  androID:ID="@+ID/v_dot"  androID:layout_wIDth="8dp"  androID:layout_height="8dp"  androID:layout_marginleft="2dp"  androID:layout_marginRight="2dp"  androID:background="@drawable/dot_normal"/></relativeLayout>

6 点点的background
dot_normal.xml

<?xml version="1.0" enCoding="utf-8"?><!-- 圆点未选中 --><shape xmlns:androID="http://schemas.androID.com/apk/res/androID" androID:shape="oval"> <solID androID:color="@color/background_color" /> <corners androID:radius="5dp" /></shape>

dot_selected.xml

<?xml version="1.0" enCoding="utf-8"?><!-- 圆点选中 --><shape xmlns:androID="http://schemas.androID.com/apk/res/androID" androID:shape="oval"> <solID androID:color="@color/red" /> <corners androID:radius="5dp" /></shape>

RecyclingPagerAdapter的源码依赖RecycleBin类,一并贴出来

public class RecycleBin { /** * VIEws that were on screen at the start of layout. This array is populated at the start of * layout,and at the end of layout all vIEw in activeVIEws are moved to scrapVIEws. * VIEws in activeVIEws represent a contiguous range of VIEws,with position of the first * vIEw store in mFirstActiveposition. */ private VIEw[] activeVIEws = new VIEw[0]; private int[] activeVIEwTypes = new int[0]; /** Unsorted vIEws that can be used by the adapter as a convert vIEw. */ private SparseArray<VIEw>[] scrapVIEws; private int vIEwTypeCount; private SparseArray<VIEw> currentScrapVIEws; public voID setVIEwTypeCount(int vIEwTypeCount) { if (vIEwTypeCount < 1) {  throw new IllegalArgumentException("Can't have a vIEwTypeCount < 1"); } //noinspection unchecked SparseArray<VIEw>[] scrapVIEws = new SparseArray[vIEwTypeCount]; for (int i = 0; i < vIEwTypeCount; i++) {  scrapVIEws[i] = new SparseArray<VIEw>(); } this.vIEwTypeCount = vIEwTypeCount; currentScrapVIEws = scrapVIEws[0]; this.scrapVIEws = scrapVIEws; } protected boolean shouldRecycleVIEwType(int vIEwType) { return vIEwType >= 0; } /** @return A vIEw from the ScrapVIEws collection. These are unordered. */ VIEw getScrapVIEw(int position,int vIEwType) { if (vIEwTypeCount == 1) {  return retrIEveFromScrap(currentScrapVIEws,position); } else if (vIEwType >= 0 && vIEwType < scrapVIEws.length) {  return retrIEveFromScrap(scrapVIEws[vIEwType],position); } return null; } /** * Put a vIEw into the ScrapVIEws List. These vIEws are unordered. * * @param scrap The vIEw to add */ voID addScrapVIEw(VIEw scrap,int position,int vIEwType) { if (vIEwTypeCount == 1) {  currentScrapVIEws.put(position,scrap); } else {  scrapVIEws[vIEwType].put(position,scrap); } if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {  scrap.setAccessibilityDelegate(null); } } /** Move all vIEws remaining in activeVIEws to scrapVIEws. */ voID scrapActiveVIEws() { final VIEw[] activeVIEws = this.activeVIEws; final int[] activeVIEwTypes = this.activeVIEwTypes; final boolean multipleScraps = vIEwTypeCount > 1; SparseArray<VIEw> scrapVIEws = currentScrapVIEws; final int count = activeVIEws.length; for (int i = count - 1; i >= 0; i--) {  final VIEw victim = activeVIEws[i];  if (victim != null) {  int whichScrap = activeVIEwTypes[i];  activeVIEws[i] = null;  activeVIEwTypes[i] = -1;  if (!shouldRecycleVIEwType(whichScrap)) {   continue;  }  if (multipleScraps) {   scrapVIEws = this.scrapVIEws[whichScrap];  }  scrapVIEws.put(i,victim);  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {   victim.setAccessibilityDelegate(null);  }  } } prunescrapVIEws(); } /** * Makes sure that the size of scrapVIEws does not exceed the size of activeVIEws. * (This can happen if an adapter does not recycle its vIEws). */ private voID prunescrapVIEws() { final int maxVIEws = activeVIEws.length; final int vIEwTypeCount = this.vIEwTypeCount; final SparseArray<VIEw>[] scrapVIEws = this.scrapVIEws; for (int i = 0; i < vIEwTypeCount; ++i) {  final SparseArray<VIEw> scrapPile = scrapVIEws[i];  int size = scrapPile.size();  final int extras = size - maxVIEws;  size--;  for (int j = 0; j < extras; j++) {  scrapPile.remove(scrapPile.keyAt(size--));  } } } static VIEw retrIEveFromScrap(SparseArray<VIEw> scrapVIEws,int position) { int size = scrapVIEws.size(); if (size > 0) {  // See if we still have a vIEw for this position.  for (int i = 0; i < size; i++) {  int fromposition = scrapVIEws.keyAt(i);  VIEw vIEw = scrapVIEws.get(fromposition);  if (fromposition == position) {   scrapVIEws.remove(fromposition);   return vIEw;  }  }  int index = size - 1;  VIEw r = scrapVIEws.valueAt(index);  scrapVIEws.remove(scrapVIEws.keyAt(index));  return r; } else {  return null; } }}

RecyclingPagerAdapter

public abstract class RecyclingPagerAdapter extends PagerAdapter { static final int IGnorE_ITEM_VIEW_TYPE = AdapterVIEw.ITEM_VIEW_TYPE_IGnorE; private final RecycleBin recycleBin; public RecyclingPagerAdapter() { this(new RecycleBin()); } RecyclingPagerAdapter(RecycleBin recycleBin) { this.recycleBin = recycleBin; recycleBin.setVIEwTypeCount(getVIEwTypeCount()); } @OverrIDe public voID notifyDataSetChanged() { recycleBin.scrapActiveVIEws(); super.notifyDataSetChanged(); } @OverrIDe public final Object instantiateItem(VIEwGroup container,int position) { int vIEwType = getItemVIEwType(position); VIEw vIEw = null; if (vIEwType != IGnorE_ITEM_VIEW_TYPE) {  vIEw = recycleBin.getScrapVIEw(position,vIEwType); } vIEw = getVIEw(position,vIEw,container); container.addVIEw(vIEw); return vIEw; } @OverrIDe public final voID destroyItem(VIEwGroup container,Object object) { VIEw vIEw = (VIEw) object; container.removeVIEw(vIEw); int vIEwType = getItemVIEwType(position); if (vIEwType != IGnorE_ITEM_VIEW_TYPE) {  recycleBin.addScrapVIEw(vIEw,position,vIEwType); } } @OverrIDe public final boolean isVIEwFromObject(VIEw vIEw,Object object) { return vIEw == object; } /** * <p> * Returns the number of types of VIEws that will be created by * {@link #getVIEw}. Each type represents a set of vIEws that can be * converted in {@link #getVIEw}. If the adapter always returns the same * type of VIEw for all items,this method should return 1. * </p> * <p> * This method will only be called when when the adapter is set on the * the {@link AdapterVIEw}. * </p> * * @return The number of types of VIEws that will be created by this adapter */ public int getVIEwTypeCount() { return 1; } /** * Get the type of VIEw that will be created by {@link #getVIEw} for the specifIEd item. * * @param position The position of the item within the adapter's data set whose vIEw type we *  want. * @return An integer representing the type of VIEw. Two vIEws should share the same type if one *   can be converted to the other in {@link #getVIEw}. Note: Integers must be in the *   range 0 to {@link #getVIEwTypeCount} - 1. {@link #IGnorE_ITEM_VIEW_TYPE} can *   also be returned. * @see #IGnorE_ITEM_VIEW_TYPE */ @SuppressWarnings("UnusedParameters") // Argument potentially used by subclasses. public int getItemVIEwType(int position) { return 0; } /** * Get a VIEw that displays the data at the specifIEd position in the data set. You can either * create a VIEw manually or inflate it from an XML layout file. When the VIEw is inflated,the * parent VIEw (GrIDVIEw,ListVIEw...) will apply default layout parameters unless you use * {@link androID.vIEw.LayoutInflater#inflate(int,VIEwGroup,boolean)} * to specify a root vIEw and to prevent attachment to the root. * * @param position The position of the item within the adapter's data set of the item whose vIEw *  we want. * @param convertVIEw The old vIEw to reuse,if possible. Note: You should check that this vIEw *  is non-null and of an appropriate type before using. If it is not possible to convert *  this vIEw to display the correct data,this method can create a new vIEw. *  Heterogeneous Lists can specify their number of vIEw types,so that this VIEw is *  always of the right type (see {@link #getVIEwTypeCount()} and *  {@link #getItemVIEwType(int)}). * @return A VIEw corresponding to the data at the specifIEd position. */ public abstract VIEw getVIEw(int position,VIEw convertVIEw,VIEwGroup container);}

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

总结

以上是内存溢出为你收集整理的Android实现带指示点的自动轮播无限循环效果全部内容,希望文章能够帮你解决Android实现带指示点的自动轮播无限循环效果所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1147650.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-31
下一篇 2022-05-31

发表评论

登录后才能评论

评论列表(0条)

保存