一 自定义viewpagerAdapter
1、最大值设置:getcount 返回 为Interger.MAXVALUE
2、轮播之后View的移除 【防止重复添加view】
2、轮播之后View的移除 【防止重复添加view】
public class ImageAdapter extends PagerAdapter {
private Context context;
//轮播需要的图片
public ArrayList<ImageView> imgs;
public ImageAdapter(Context context, ArrayList<ImageView> imgs) {
this.context = context;
this.imgs = imgs;
}
/**
* ViewPager的边界
*
* @return
*/
@Override
public int getCount() {
//设置成最大,使无限循环
return Integer.MAX_VALUE;
}
@Override
public boolean isViewFromObject(View view, Object object) {
return view == object;
}
/**
* 由于我们在instantiateItem()方法中已经处理了remove的逻辑,
* 因此这里并不需要处理。实际上,实验表明这里如果加上了remove的调用,
* 则会出现ViewPager的内容为空的情况。
*
* @param container
* @param position
* @param object
*/
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
//警告:不要在这里调用removeView
}
/**
* @param container
* @param position
* @return 对position进行求模操作
* 因为当用户向左滑时position可能出现负值,所以必须进行处理
*/
@Override
public Object instantiateItem(ViewGroup container, int position) {
//对Viewpager页号求模去除View列表中要显示的项
position %= imgs.size();
if (position < 0) {
position = imgs.size() + position;
}
ImageView view = imgs.get(position);
//如果View已经在之前添加到了一个父组件,则必须先remove,否则会抛出IllegalStateException。
ViewParent viewParent = view.getParent();
if (viewParent != null) {
ViewGroup parent = (ViewGroup) viewParent;
parent.removeView(view);
}
container.addView(view);
return view;
}
}
二 handler 计时发消息设置 轮播currentItem
public class ImageHandler extends Handler {
/**
* 请求更新显示的View
*/
public static final int MSG_UPDATE_IMAGE = 1;
/**
* 请求暂停轮播
*/
public static final int MSG_KEEP_SILENT = 2;
/**
* 请求恢复轮播。
*/
public static final int MSG_BREAK_SILENT = 3;
/**
* 记录最新的页号,当用户手动滑动时需要记录新页号,否则会使轮播的页面出错。
* 例如当前如果在第一页,本来准备播放的是第二页,而这时候用户滑动到了末页,
* 则应该播放的是第一页,如果继续按照原来的第二页播放,则逻辑上有问题。
*/
public static final int MSG_PAGE_CHANGED = 4;
//轮播间隔时间
public static final long MSG_DELAY = 2000;
//这里使用弱引用避免Handler泄露
private WeakReference<MainActivity> weakReference;
private int currentItem = Integer.MAX_VALUE / 2;
public ImageHandler(WeakReference<MainActivity> wk) {
weakReference = wk;
}
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
MainActivity mainActivity = weakReference.get();
if (mainActivity == null) {
//mainActivity已经回收,无需继续处理UI
return;
}
//检查消息队列并移除未发送的消息,这主要是避免在复杂环境下消息出现重复等问题。
/**
* 这段会把第一次的自动轮播事件吃掉,所以可以加个条件,Position!=Max/2的时候才清除事件.因为第一次Position一定等于Max/2
*/
if ((mainActivity.mImageHandler.hasMessages(MSG_UPDATE_IMAGE)) && (currentItem != Integer.MAX_VALUE / 2)) {
mainActivity.mImageHandler.removeMessages(MSG_UPDATE_IMAGE);
}
switch (msg.what) {
case MSG_UPDATE_IMAGE:
currentItem++;
mainActivity.ChanggeViewPagerCurrentItem(currentItem);
//准备下次播放
mainActivity.mImageHandler.sendEmptyMessageDelayed(MSG_UPDATE_IMAGE, MSG_DELAY);
break;
case MSG_KEEP_SILENT:
//只要不发送消息就暂停了
break;
case MSG_BREAK_SILENT:
mainActivity.mImageHandler.sendEmptyMessageDelayed(MSG_UPDATE_IMAGE, MSG_DELAY);
break;
case MSG_PAGE_CHANGED:
//记录当前的页号,避免播放的时候页面显示不正确。
currentItem = msg.arg1;
break;
default:
break;
}
}
}
三 在布局中 根据从服务器获取的image个数 决定 生成添加多少个圆点引导 根据MAX_VALUE/2 计算轮播起始是第一个的
position
public class MainActivity extends AppCompatActivity {
private ViewPager vp;
private ArrayList<ImageView> imageViews;
private LinearLayout ll_icon_container;
// 实际开发中这个数量是根据后台下发的图片个数 来决定创建多少个小圆点
private int imageCount = 15;
public ImageHandler mImageHandler;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initVIew();
initListener();
}
private void initVIew() {
vp = (ViewPager) findViewById(R.id.main_picturecarousel_vp);
ll_icon_container = findViewById(R.id.ll_icon_container);
imageViews = new ArrayList<>();
LayoutInflater inflater = LayoutInflater.from(this);
ll_icon_container.removeAllViews();
for (int i = 0; i < imageCount; i++) {
ImageView imgv = (ImageView) inflater.inflate(R.layout.image_item, null);
imgv.setImageResource(R.mipmap.ic_launcher);
imageViews.add(imgv);
//初始化原点点
ImageView icon = (ImageView) inflater.inflate(R.layout.icon_view, null);
ll_icon_container.addView(icon);
}
vp.setAdapter(new ImageAdapter(MainActivity.this, imageViews));
mImageHandler = new ImageHandler(new WeakReference<>(this));
}
private void initListener() {
vp.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
retSetIcon(position);
mImageHandler.sendMessage(Message.obtain(mImageHandler, ImageHandler.MSG_PAGE_CHANGED, position, 0));
}
@Override
public void onPageScrollStateChanged(int state) {
switch (state) {
case ViewPager.SCROLL_STATE_DRAGGING:
mImageHandler.sendEmptyMessage(ImageHandler.MSG_KEEP_SILENT);
break;
case ViewPager.SCROLL_STATE_IDLE:
mImageHandler.sendEmptyMessageDelayed(ImageHandler.MSG_UPDATE_IMAGE, ImageHandler.MSG_DELAY);
break;
default:
break;
}
}
});
setFirstIndex();
//开始轮播效果
mImageHandler.sendEmptyMessageDelayed(ImageHandler.MSG_UPDATE_IMAGE, ImageHandler.MSG_DELAY);
}
/**
* 设置第一个图片的下标
*/
private void setFirstIndex(int count) {
for (int i = 250; i < 500; i++) {
if (i % count == 0) {
mViewPager.setCurrentItem(i);
Log.e("flag","------------------拿到的数字为:"+i);
break;
}
}
}
/**
* 更新小圆点状态
*
* @param position
*/
private void retSetIcon(int position) {
for (int i = 0; i < ll_icon_container.getChildCount(); i++) {
((ImageView) ll_icon_container.getChildAt(i)).setImageResource(R.mipmap.select_no);
}
((ImageView) ll_icon_container.getChildAt(position % imageCount)).setImageResource(R.mipmap.select_icon);
}
/**
* 轮播时设置当前的条目
*
* @param position
*/
public void ChanggeViewPagerCurrentItem(int position) {
vp.setCurrentItem(position);
retSetIcon(position);
}
}
demo地址为https://download.csdn.net/download/xuwb123xuwb/10327452