效果图如下:
xml布局文件
代码的实现
工程结构如下图
第一步:初始化数据
/**
*初始化数据
*/
//初始化图片轮播的图片
private void initData() {
int[] imageResIDs = {
R.mipmap.a,
R.mipmap.b,
R.mipmap.c,
R.mipmap.d,
R.mipmap.e
};
mImageList = new ArrayList<>();
ImageView iv;
for (int i = 0; i < imageResIDs.length; i++) {
iv = new ImageView(this);
iv.setBackgroundResource(imageResIDs[i]);
mImageList.add(iv);
//初始化显示每张图片下面现实的文字
imageDescs= new String[]{
"今年二十七八岁,我最喜欢的事就是睡觉",
"懒虫,起床了,要上班了",
"我翻了个身,想着如果今天是周末多好",
"终于爬起来,坐在沙发上一脸懵逼",
"一个人早餐就随便吃点"
};
}
}
第二步:设置viewpager适配器
/**
*新建一个adapter包,新建适配类如下
*/
public class MyPagerAdapter extends PagerAdapter {
private List imageList;
private ViewPager viewPager;
public MyPagerAdapter(List imageList, ViewPager viewPager) {
this.imageList = imageList;
this.viewPager = viewPager;
}
/**
* 返回的int的值, 会作为ViewPager的总长度来使用.
*/
@Override
public int getCount() {
return Integer.MAX_VALUE;//Integer.MAX_VALUE伪无限循环
}
/**
* 判断是否使用缓存, 如果返回的是true, 使用缓存. 不去调用instantiateItem方法创建一个新的对象
*/
@Override
public boolean isViewFromObject(View view, Object object) {
return view == object;
}
/**
* 初始化一个条目
* position 就是当前需要加载条目的索引
*/
@Override
public Object instantiateItem(ViewGroup container, int position) {
// 把position对应位置的ImageView添加到ViewPager中
ImageView iv = imageList.get(position % imageList.size());
viewPager.addView(iv);
// 把当前添加ImageView返回回去.
return iv;
}
/**
* 销毁一个条目
* position 就是当前需要被销毁的条目的索引
*/
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
// 把ImageView从ViewPager中移除掉
viewPager.removeView(imageList.get(position % imageList.size()));
}
}
第三步:给viewpager设置轮播监听器
/**
* 当ViewPager页面被选中时, 触发此方法.
* @param position 当前被选中的页面的索引
*/
@Override
public void onPageSelected(int position) {
//伪无限循环,滑到最后一张图片又从新进入第一张图片
int newPosition = position % mImageList.size();
// 把当前选中的点给切换了, 还有描述信息也切换
mTvImageDesc.setText(imageDescs[newPosition]);//图片下面设置显示文本
// 把当前的索引赋值给前一个索引变量, 方便下一次再切换.
previousPosition = newPosition;
}
@Override
public void onPageScrollStateChanged(int state) {
}
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
第四步:设置刚打开app时显示的图片和文字
/**
* 设置刚进入app时,显示的图片和文字
*/
private void setFirstLocation() {
mTvImageDesc.setText(imageDescs[previousPosition]);
// 把ViewPager设置为默认选中Integer.MAX_VALUE / 2,从十几亿次开始轮播图片,达到无限循环目的;
int m = (Integer.MAX_VALUE / 2) % mImageList.size();
int currentPosition = Integer.MAX_VALUE / 2 - m;
mViewPager.setCurrentItem(currentPosition);
}
第五步: 设置自动播放,每隔3秒换一张图片
/**
* 每隔3秒自动播放图片
*/
private void autoPlayView() {
//自动播放图片
new Thread(new Runnable() {
@Override
public void run() {
while (!isStop){
runOnUiThread(new Runnable() {
@Override
public void run() {
mViewPager.setCurrentItem(mViewPager.getCurrentItem() + 1);
}
});
SystemClock.sleep(3000);
}
}
}).start();
}
第六步: 当Activity销毁时取消图片自动播放
/**
*当Activity销毁时取消图片自动播放
*/
@Override
protected void onDestroy() {
super.onDestroy();
isStop = true;
}
细节问题处理
如果发现左边图片的索引是负数, 小于0, 就不会预加载.
如果发现右边的图片是索引是大于等于总图片的个数,也不会预加载. 例如:总图片是:5, 右边的图片是第6张。
图片无限循环实现
1.设置是适配器返回的长度为Integer的最大值
@Override
public int getCount() {
return Integer.MAX_VALUE;
}
2.将position设置为如下
//伪无限循环,滑到最后一张图片又从新进入第一张图片
int newPosition = position % mImageList.size();
附上全部的代码
MainActiviy
public class MainActivity extends AppCompatActivity implements ViewPager.OnPageChangeListener{
@BindView(R.id.view_pager)
ViewPager mViewPager;
@BindView(R.id.tv_image_desc)
TextView mTvImageDesc;
private List mImageList;
private String[] imageDescs;
private int previousPosition = 0; // 前一个被选中的position
private boolean isStop = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
initView();
autoPlayView();
}
/**
* 第五步: 设置自动播放,每隔3秒换一张图片
*/
private void autoPlayView() {
//自动播放图片
new Thread(new Runnable() {
@Override
public void run() {
while (!isStop){
runOnUiThread(new Runnable() {
@Override
public void run() {
mViewPager.setCurrentItem(mViewPager.getCurrentItem() + 1);
}
});
SystemClock.sleep(3000);
}
}
}).start();
}
private void initView() {
initData();
MyPagerAdapter mAdapter = new MyPagerAdapter(mImageList, mViewPager);
mViewPager.setAdapter(mAdapter);//第二步:设置viewpager适配器
mViewPager.addOnPageChangeListener(this);
setFirstLocation();
}
/**
* 第四步:设置刚打开app时显示的图片和文字
*/
private void setFirstLocation() {
mTvImageDesc.setText(imageDescs[previousPosition]);
// 把ViewPager设置为默认选中Integer.MAX_VALUE / 2,从十几亿次开始轮播图片,达到无限循环目的;
int m = (Integer.MAX_VALUE / 2) % mImageList.size();
int currentPosition = Integer.MAX_VALUE / 2 - m;
mViewPager.setCurrentItem(currentPosition);
}
/**
* 第一步:初始化数据
*/
//初始化图片轮播的图片
private void initData() {
int[] imageResIDs = {
R.mipmap.a,
R.mipmap.b,
R.mipmap.c,
R.mipmap.d,
R.mipmap.e
};
mImageList = new ArrayList<>();
ImageView iv;
for (int i = 0; i < imageResIDs.length; i++) {
iv = new ImageView(this);
iv.setBackgroundResource(imageResIDs[i]);
mImageList.add(iv);
//初始化显示每张图片下面现实的文字
imageDescs= new String[]{
"今年二十七八岁,我最喜欢的事就是睡觉",
"懒虫,起床了,要上班了",
"我翻了个身,想着如果今天是周末多好",
"终于爬起来,坐在沙发上一脸懵逼",
"一个人早餐就随便吃点"
};
}
}
/**
* 第三步:给viewpager设置轮播监听器
* viewpager的监听器
* 当ViewPager页面被选中时, 触发此方法.
* @param position 当前被选中的页面的索引
*/
@Override
public void onPageSelected(int position) {
//伪无限循环,滑到最后一张图片又从新进入第一张图片
int newPosition = position % mImageList.size();
// 把当前选中的点给切换了, 还有描述信息也切换
mTvImageDesc.setText(imageDescs[newPosition]);//图片下面设置显示文本
// 把当前的索引赋值给前一个索引变量, 方便下一次再切换.
previousPosition = newPosition;
}
@Override
public void onPageScrollStateChanged(int state) {
}
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
/**
* 第六步: 当Activity销毁时取消图片自动播放
*/
@Override
protected void onDestroy() {
super.onDestroy();
isStop = true;
}
}
MyPagerAdapter
public class MyPagerAdapter extends PagerAdapter {
private List imageList;
private ViewPager viewPager;
public MyPagerAdapter(List imageList, ViewPager viewPager) {
this.imageList = imageList;
this.viewPager = viewPager;
}
/**
* 返回的int的值, 会作为ViewPager的总长度来使用.
*/
@Override
public int getCount() {
return Integer.MAX_VALUE;//Integer.MAX_VALUE伪无限循环
}
/**
* 判断是否使用缓存, 如果返回的是true, 使用缓存. 不去调用instantiateItem方法创建一个新的对象
*/
@Override
public boolean isViewFromObject(View view, Object object) {
return view == object;
}
/**
* 初始化一个条目
* position 就是当前需要加载条目的索引
*/
@Override
public Object instantiateItem(ViewGroup container, int position) {
// 把position对应位置的ImageView添加到ViewPager中
ImageView iv = imageList.get(position % imageList.size());
viewPager.addView(iv);
// 把当前添加ImageView返回回去.
return iv;
}
/**
* 销毁一个条目
* position 就是当前需要被销毁的条目的索引
*/
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
// 把ImageView从ViewPager中移除掉
viewPager.removeView(imageList.get(position % imageList.size()));
}
}