栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 移动开发 > Android

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

Android 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

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

想要实现无限轮播,一直向左滑动,当到最后一个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布局为

 
 
 
 
 

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

 `public class Indicator1Adapter extends RecyclingPagerAdapter {
 private List imageIdList;
 Context context;
 //是否循环(创造构造方法,在activity里设置是否)
 //集合大小
 private int size;

 public Indicator1Adapter(List 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();
 }

 
 public boolean isInfiniteLoop() {
  return isInfiniteLoop;
 }

 
 public Indicator1Adapter setInfiniteLoop(boolean isInfiniteLoop) {
  this.isInfiniteLoop = isInfiniteLoop;
  return this;
 }

 
 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 然后我们的小点点还没有使用呢
这里我写了方法:


 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()){
      // 圆点选中
      
      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点点布局:


 
 

6 点点的background
dot_normal.xml



 

 


dot_selected.xml



 
 

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

public class RecycleBin {
 
 private View[] activeViews = new View[0];
 private int[] activeViewTypes = new int[0];

 
 private SparseArray[] scrapViews;

 private int viewTypeCount;

 private SparseArray currentScrapViews;

 public void setViewTypeCount(int viewTypeCount) {
 if (viewTypeCount < 1) {
  throw new IllegalArgumentException("Can't have a viewTypeCount < 1");
 }
 //noinspection unchecked
 SparseArray[] scrapViews = new SparseArray[viewTypeCount];
 for (int i = 0; i < viewTypeCount; i++) {
  scrapViews[i] = new SparseArray();
 }
 this.viewTypeCount = viewTypeCount;
 currentScrapViews = scrapViews[0];
 this.scrapViews = scrapViews;
 }

 protected boolean shouldRecycleViewType(int viewType) {
 return viewType >= 0;
 }

 
 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;
 }

 
 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);
 }
 }

 
 void scrapActiveViews() {
 final View[] activeViews = this.activeViews;
 final int[] activeViewTypes = this.activeViewTypes;
 final boolean multipleScraps = viewTypeCount > 1;

 SparseArray 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();
 }

 
 private void pruneScrapViews() {
 final int maxViews = activeViews.length;
 final int viewTypeCount = this.viewTypeCount;
 final SparseArray[] scrapViews = this.scrapViews;
 for (int i = 0; i < viewTypeCount; ++i) {
  final SparseArray 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 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, int position, 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;
 }

 
 public int getViewTypeCount() {
 return 1;
 }

 
 @SuppressWarnings("UnusedParameters") // Argument potentially used by subclasses.
 public int getItemViewType(int position) {
 return 0;
 }

 
 public abstract View getView(int position, View convertView, ViewGroup container);
}

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

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/160716.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号