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

Android Viewpager实现无限循环轮播图

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

Android Viewpager实现无限循环轮播图

在网上找了很多viewpager实现图片轮播的,但是大多数通过以下方式在PagerAdapter的getCount()返回一个无限大的数,来实现 伪无限

@Override
 public int getCount() {
  return Integer.MAX_VALUE;//返回一个无限大的值,可以 无限循环
 }

虽然通过这种方式是能达到效果,但是从严格意义上来说并不是真正的无限。

假如有五张轮播图 item的编号为(0,1,2,3,4) 要想实现 无限循环  我们在这五张的头部和尾部各加一张即(5+2)张,item编号为(0,1,2,3,4,5,6)其中编号为0,6的两张不做展示只是为了做循环轮播的铺垫,使得播放更加平滑。

1、当我们从编号为5 右滑的时候到了编号6 这时候就将当前页面设置为1

2、当我们从编号为1左滑的时候到了编号0  这时候就将当前页面设置为5

这么做之后就可以实现无限轮播  怎么保证从编号6跳转编号1的时候不出现页面停顿 突然跳到下一页的现象呢?

public Object instantiateItem (ViewGroup container, int position)

在指定的位置创建页面;适配器负责添加view到这个容器中,然而它只保证在finishUpdate(ViewGroup)返回时才完成。

public void destroyItem (ViewGroup container, int position, Object object)

删除指定位置的页面;适配器负责从view容器中删除view,然而它只保证在finishUpdate(ViewGroup)返回时才完成。

所以说 重点就在于finishUpdate(ViewGroup)这个方法 其实无论是创建view添加到容器中  还是 销毁view 都是在此方法结束之后执行的

换句话说  就是 我在这个方法里让页面完成从 编号5跳转到编号1 或者从编号1跳转到编号5,此方法完成时 视图还未完成创建或者 销毁 这样也就不会出现 页面停顿 突然跳到下一页的现象。

@Override
 public void finishUpdate(ViewGroup container) {
  super.finishUpdate(container);
 
  int position = viewPager.getCurrentItem();
  
  if (position == 0) {
   position = simpleDraweeViewList.size() - 2;
   viewPager.setCurrentItem(position,false);
  } else if (position == simpleDraweeViewList.size() - 1) {
   position = 1;
   viewPager.setCurrentItem(position,false);
  }
 }

话不多说,上代码:

布局文件:



 
 
 
  
 
  
 
   
 
   
 
  
 
 
 

最主要的PagerAdapter:

import android.content.Context;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
 
import com.facebook.drawee.view.SimpleDraweeView;
 
import java.util.List;
 
public class ImagesPagerAdapter extends PagerAdapter {
 private List simpleDraweeViewList;
 private ViewPager viewPager;
 private Context context;
 
 private SimpleDraweeView simpleDraweeView;
 
 public ImagesPagerAdapter(List simpleDraweeViewList, ViewPager viewPager, Context context) {
  this.simpleDraweeViewList = simpleDraweeViewList;
  this.viewPager = viewPager;
  this.context = context;
 }
 
 @Override
 public int getCount() {
 return simpleDraweeViewList.size();
 }
 
 //删除指定位置的页面;适配器负责从view容器中删除view,然而它只保证在finishUpdate(ViewGroup)返回时才完成。
 @Override
 public void destroyItem(ViewGroup container, int position, Object object) {
  // 把ImageView从ViewPager中移除掉
  viewPager.removeView(simpleDraweeViewList.get(position));
  //super.destroyItem(container, position, object);
 }
 
 //是否获取缓存
 @Override
 public boolean isViewFromObject(View view, Object object) {
  return view == object;
 }
 
 
 //实例化Item
 //在指定的位置创建页面;适配器负责添加view到这个容器中,然而它只保证在finishUpdate(ViewGroup)返回时才完成。
 @Override
 public Object instantiateItem(ViewGroup container, int position) {
  simpleDraweeView = simpleDraweeViewList.get(position);
  viewPager.addView(simpleDraweeView);
  return simpleDraweeView;
 }
 
 @Override
 public int getItemPosition(Object object) {
  return POSITION_NONE;
 }
 
 //无论是创建view添加到容器中 还是 销毁view 都是在此方法结束之后执行的
 @Override
 public void finishUpdate(ViewGroup container) {
  super.finishUpdate(container);
 
  int position = viewPager.getCurrentItem();
  
  if (position == 0) {
   position = simpleDraweeViewList.size() - 2;
   viewPager.setCurrentItem(position,false);
  } else if (position == simpleDraweeViewList.size() - 1) {
   position = 1;
   viewPager.setCurrentItem(position,false);
  }
 }
 
 
 

}
import android.app.Activity;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.support.v4.content.ContextCompat;
import android.support.v4.view.ViewPager;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.TextView;
 
import com.facebook.drawee.view.SimpleDraweeView;
 
import java.util.ArrayList;
import java.util.List;
 
 
 
public class ImageCarousel {
 private Context context;
 private ViewPager viewPager;
 private TextView tvTitle;
 private LinearLayout dotsRoot;
 private int time;
 
 
 private List dots;//小点
 private int previousPosition = 1;//前一个被选中的position
 private List simpleDraweeViewList;
 private String[] titles;//标题数组
 
 private ImagesPagerAdapter adapter;
 
 private AutoPlayThread autoPlayThread;
 private volatile boolean isExit = true;
 
 private static final int FIRST_PAGE = 1;
 
 
 public ImageCarousel(Context context, ViewPager viewPager, TextView tvTitle,
List dots, int time) {
  this.context = context;
  this.viewPager = viewPager;
  this.tvTitle = tvTitle;
  this.dots = dots;
  this.time = time;
  Log.e("image", "构造方法");
 }
 
 
 
 
 public ImageCarousel init(List simpleDraweeViewList, String[] titles) {
  this.simpleDraweeViewList = simpleDraweeViewList;
  this.titles = titles;
  Log.e("image", "init");
  autoPlayThread = new AutoPlayThread();
 
  return this;
 }
 
 
 public void reload(List simpleDraweeViewList, String[] titles) {
  init(simpleDraweeViewList, titles);
  previousPosition = 0;
  start();
 }
 
 
 public void start() {
  if (adapter != null) {
   adapter = null;
  }
  adapter = new ImagesPagerAdapter(this.simpleDraweeViewList, viewPager, context);
  viewPager.setAdapter(adapter);
  viewPager.addonPageChangeListener(new ViewPager.onPageChangeListener() {
   @Override
   public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
 
   }
 
   //当被选择
   @Override
   public void onPageSelected(int position) {
 
    int currentPosition = 1;
    if (position == simpleDraweeViewList.size() - 1) {
     // 设置当前值为1
     currentPosition = FIRST_PAGE;
    } else if (position == 0) {
     // 如果索引值为0了,就设置索引值为倒数第二个
     currentPosition = simpleDraweeViewList.size() - 2;
    } else {
     currentPosition = position;
    }
 
    // 把当前选中的点给切换了, 还有描述信息也切换
    tvTitle.setText(titles[currentPosition]);//图片下面设置显示文本
    //设置轮播点 可设置成传入的图
 
    Log.d("dots", "previousPosition=" + previousPosition + " currentPosition=" + currentPosition);
    dots.get(previousPosition-1).setBackgroundResource(R.drawable.ic_dot_focused);
    dots.get(currentPosition-1).setBackgroundResource(R.drawable.ic_dot_normal);
    // 把当前的索引赋值给前一个索引变量, 方便下一次再切换.
    previousPosition = currentPosition;
   }
 
   @Override
   public void onPageScrollStateChanged(int state) {
 // SCROLL_STATE_IDLE :空闲状态 
 // SCROLL_STATE_DRAGGING :滑动状态 
 // SCROLL_STATE_SETTLING :滑动后滑翔的状态
    if (state == ViewPager.SCROLL_STATE_DRAGGING) {
 
    } else if(state == ViewPager.SCROLL_STATE_IDLE){
  
 }
   }
  });
 
  setFirstLocation();
  //autoPlayThread.start();
 
 }
 
 
 private void setFirstLocation() {
  tvTitle.setText(titles[0]);
  dots.get(0).setBackgroundResource(R.drawable.ic_dot_normal);
  viewPager.setCurrentItem(1);
 }
 
 
 private void setAutoPlay(boolean b) {
  
 }
 
 
 public void stopAutoPlay() {
  if (autoPlayThread != null) {
   Log.e("thrad", "暂停");
   isExit = true;
   autoPlayThread.interrupt();
   autoPlayThread = null;
  }
 }
 
 
 public void startAutoPlay() {
  Log.e("thrad", "开始");
  isExit = false;
  autoPlayThread = null;
  autoPlayThread = new AutoPlayThread();
  autoPlayThread.start();
 }
 
 
 class AutoPlayThread extends Thread {
 
  @Override
  public synchronized void run() {
   while (!isExit) {
    try {
     Thread.sleep(time);
    } catch (InterruptedException e) {
     Log.e("thrad", "强制请求退出线程");
     break;
    }
    ((Activity) context).runonUiThread(new Runnable() {
     @Override
     public void run() {
      viewPager.setCurrentItem(viewPager.getCurrentItem() + 1);
     }
    });
 
    if (this.interrupted()) {
     Log.e("thrad", "已经是停止状态了,我要退出了");
     break;
    }
   }
 
  }
 
 }
 
}

mainActivity.java:

import android.app.Activity;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.support.v4.content.ContextCompat;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.LinearLayout;
import android.widget.TextView;
 
import com.facebook.drawee.backends.pipeline.Fresco;
import com.facebook.drawee.backends.pipeline.PipelineDraweeController;
import com.facebook.drawee.drawable.ScalingUtils;
import com.facebook.drawee.generic.GenericDraweeHierarchy;
import com.facebook.drawee.generic.GenericDraweeHierarchyBuilder;
import com.facebook.drawee.view.SimpleDraweeView;
import com.facebook.imagepipeline.common.ResizeOptions;
import com.facebook.imagepipeline.request.ImageRequest;
import com.facebook.imagepipeline.request.ImageRequestBuilder;
 
import java.util.ArrayList;
import java.util.List;
 
public class MainActivity extends AppCompatActivity implements View.onClickListener {
 
 // 图片轮播控件
 private ViewPager mViewPager;
 private TextView mTvPagerTitle;
 private LinearLayout mLineLayoutDot;
 private ImageCarousel imageCarousel;
 private List dots;//小点
 
 // 图片数据,包括图片标题、图片链接、数据、点击要打开的网站(点击打开的网页或一些提示指令)
 private List imageInfoList;
 
 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  initView();
  initEvent();
  imageStart();
 
 }
 
 @Override
 public void onClick(View v) {
 
 }
 
 
 private void initEvent() {
  imageInfoList = new ArrayList<>();
 imageInfoList.add(new ImageInfo(1, "图片5,公告5啦啦啦啦", "", "/image/h%3D300/sign=73443062281f95cab9f594b6f9177fc5/72f082025aafa40fafb5fbc1a664034f78f019be.jpg", ""));
  imageInfoList.add(new ImageInfo(2, "图片1,公告1啦啦啦啦", "", "/image/pic/item/6159252dd42a2834a75bb01156b5c9ea15cebf2f.jpg", ""));
  imageInfoList.add(new ImageInfo(3, "图片2,公告2啦啦啦啦", "", "/image/h%3D300/sign=cfce96dfa251f3dedcb2bf64a4eff0ec/4610b912c8fcc3ce912597269f45d688d43f2039.jpg", ""));
  imageInfoList.add(new ImageInfo(4, "图片3,公告3啦啦啦啦", "", "/image/pic/item/6a600c338744ebf85ed0ab2bd4f9d72a6059a705.jpg", ""));
  imageInfoList.add(new ImageInfo(5, "图片4,公告4啦啦啦啦", "", "/image/h%3D300/sign=8ad802f3801001e9513c120f880e7b06/a71ea8d3fd1f4134be1e4e64281f95cad1c85efa.jpg", ""));
  imageInfoList.add(new ImageInfo(6, "图片5,公告5啦啦啦啦", "", "/image/h%3D300/sign=73443062281f95cab9f594b6f9177fc5/72f082025aafa40fafb5fbc1a664034f78f019be.jpg", ""));
 imageInfoList.add(new ImageInfo(7, "图片1,公告1啦啦啦啦", "", "/image/pic/item/6159252dd42a2834a75bb01156b5c9ea15cebf2f.jpg", ""));
 
 }
 
 
 private void initView() {
 
  mViewPager = findViewById(R.id.viewPager);
  mTvPagerTitle = findViewById(R.id.tv_pager_title);
  mLineLayoutDot = findViewById(R.id.lineLayout_dot);
 
 }
 
 private void imageStart() {
  //设置图片轮播
  int[] imgaeIds = new int[]{R.id.pager_image1, R.id.pager_image2, R.id.pager_image3, R.id.pager_image4,
    R.id.pager_image5, R.id.pager_image6, R.id.pager_image7, R.id.pager_image8};
  String[] titles = new String[imageInfoList.size()];
  List simpleDraweeViewList = new ArrayList<>();
 
  for (int i = 0; i < imageInfoList.size(); i++) {
   titles[i] = imageInfoList.get(i).getTitle();
   SimpleDraweeView simpleDraweeView = new SimpleDraweeView(this);
   simpleDraweeView.setAspectRatio(1.78f);
   // 设置一张默认的图片
   GenericDraweeHierarchy hierarchy = new GenericDraweeHierarchyBuilder(this.getResources())
     .setPlaceholderImage(ContextCompat.getDrawable(this, R.drawable.defult), ScalingUtils.ScaleType.CENTER_CROP).build();
   simpleDraweeView.setHierarchy(hierarchy);
   simpleDraweeView.setLayoutParams(new AbsListView.LayoutParams(AbsListView.LayoutParams.MATCH_PARENT, AbsListView.LayoutParams.WRAP_CONTENT));
 
   //加载高分辨率图片;
   ImageRequest imageRequest = ImageRequestBuilder.newBuilderWithSource(Uri.parse(imageInfoList.get(i).getImage()))
     .setResizeOptions(new ResizeOptions(1280, 720))
     .build();
   PipelineDraweeController controller = (PipelineDraweeController) Fresco.newDraweeControllerBuilder()
     //.setLowResImageRequest(ImageRequest.fromUri(Uri.parse(listItemBean.test_pic_low))) //在加载高分辨率图片之前加载低分辨率图片
     .setImageRequest(imageRequest)
     .setOldController(simpleDraweeView.getController())
     .build();
   simpleDraweeView.setController(controller);
 
   simpleDraweeView.setId(imgaeIds[i]);//给view设置id
   simpleDraweeView.setTag(imageInfoList.get(i));
   simpleDraweeView.setonClickListener(this);
   titles[i] = imageInfoList.get(i).getTitle();
   simpleDraweeViewList.add(simpleDraweeView);
 
  }
 
  dots = addDots(mLineLayoutDot, fromResToDrawable(this, R.drawable.ic_dot_focused), simpleDraweeViewList.size());
  imageCarousel = new ImageCarousel(this, mViewPager, mTvPagerTitle, dots, 5000);
  imageCarousel.init(simpleDraweeViewList, titles)
    .startAutoPlay();
  imageCarousel.start();
 
 }
 
 
 
 private int addDot(final LinearLayout linearLayout, Drawable backgount) {
  final View dot = new View(this);
  LinearLayout.LayoutParams dotParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
    ViewGroup.LayoutParams.WRAP_CONTENT);
  dotParams.width = 16;
  dotParams.height = 16;
  dotParams.setMargins(4, 0, 4, 0);
  dot.setLayoutParams(dotParams);
  dot.setBackground(backgount);
  dot.setId(View.generateViewId());
  ((Activity) this).runonUiThread(new Runnable() {
   @Override
   public void run() {
    linearLayout.addView(dot);
   }
  });
 
  return dot.getId();
 }
 
 
 
 public static Drawable fromResToDrawable(Context context, int resId) {
  return ContextCompat.getDrawable(context, resId);
 }
 
 
 private List addDots(final LinearLayout linearLayout, Drawable backgount, int number) {
  List dots = new ArrayList<>();
  for (int i = 2; i < number; i++) { // 注意这里的 i 从 2 开始,只画出5个点
 
   int dotId = addDot(linearLayout, backgount);
   dots.add(findViewById(dotId));
 
  }
  return dots;
 }
 
 
}

ic_dot_focused.xml:


 

ic_dot_normal.xml:


 

当然这里主要是实现真正的无限轮播,其中对于 用户手动滑动图片时需要暂停轮播没有做相关处理。

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

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

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

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