Android中级:轮播图(一):实现ViewPager的无线自动循环
2016-08-23 01:10
489 查看
无限自动循环 = 无限循环 + 自动循环 无限循环 = 无限向左循环 + 无限向右循环 向左:图片由;右向左滑动 向右:图片由右向左滑动
接下来我们通过demo一步步的实现无限向右循环–>无限向左循环–>自动循环
Demo中viewpager中放有5张图片,我们可以向左向右滑动,但是
若当前页是第一页,则无法再向右滑动。
若当前页是最后一页,则无法再向左滑动。
一般情况:没有循环,需手滑
activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#1A237E" tools:context=".MainActivity" > <android.support.v4.view.ViewPager android:id="@+id/viewpager" android:layout_width="match_parent" android:layout_height="300dp" android:layout_centerInParent="true" /> </RelativeLayout>
MainActivity.java
public class MainActivity extends Activity { protected static final String tag = "MainActivity"; private ViewPager viewpager; private List<ImageView> imageList = new ArrayList<ImageView>(); private Context context; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); context = this; initData(); viewpager = (ViewPager) findViewById(R.id.viewpager); viewpager.setAdapter(new MyAdapter()); } private void initData() { imageList.clear(); ImageView iva = new ImageView(context); iva.setBackgroundResource(R.drawable.a); ImageView ivb = new ImageView(context); ivb.setBackgroundResource(R.drawable.b); ImageView ivc = new ImageView(context); ivc.setBackgroundResource(R.drawable.c); ImageView ivd = new ImageView(context); ivd.setBackgroundResource(R.drawable.d); ImageView ive = new ImageView(context); ive.setBackgroundResource(R.drawable.e); imageList.add(iva); imageList.add(ivb); imageList.add(ivc); imageList.add(ivd); imageList.add(ive); } public class MyAdapter extends PagerAdapter{ //表示viewpager共存放了多少个页面 @Override public int getCount() { return imageList.size(); } @Override public boolean isViewFromObject(View view, Object object) { return view == object; } @Override public Object instantiateItem(ViewGroup container, int position) { container.addView(imageList.get(position)); return imageList.get(position); } @Override public void destroyItem(ViewGroup container, int position, Object object) { container.removeView((View)object); } } }
添加无限向左循环
可以无限次的向左滑动,需要对PagerAdapter的2个方法进行修改return Integer.MAX_VALUE:viewpager里面有几乎无穷多个object imageList.get(position % imageList.size());防止角标越界
//表示viewpager共存放了多少个页面 @Override public int getCount() { return Integer.MAX_VALUE;//我们设置viewpager中有Integer.MAX_VALUE个页面 }
/** * position % imageList.size() 而不是position,是为了防止角标越界异常 * 因为我们设置了viewpager子页面的数量有Integer.MAX_VALUE,而imageList的数量只是5。 */ @Override public Object instantiateItem(ViewGroup container, int position) { container.addView(imageList.get(position % imageList.size())); return imageList.get(position % imageList.size()); }
但是这样暴露一个缺点,就是可以向左滑动,但是当前页是第一页的时候,无法向右滑动,因为第一页的position是0。 解决方法: 给viewpager设置当前页是第1000页,这样当前页的左边还有999页,右边还有Integer.MAX_VALUE - 1000页, 无论是999,还是(Integer.MAX_VALUE - 1000),一般情况下是滑不到第一页或最后一页的。 当然1000是自己设置的,也可以设置多加几个0。
添加无限向右循环
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); context = this; initData(); viewpager = (ViewPager) findViewById(R.id.viewpager); viewpager.setAdapter(new MyAdapter()); viewpager.setCurrentItem(1000);//当前页是第1000页 }
添加自动循环
上面只是实现了无限循环,但还是用手动的,我们需要它每个一段时间(2秒)滑动一次。这就需要用到handlerint msgWhat = 0; private Handler handler = new Handler(){ public void handleMessage(android.os.Message msg) { viewpager.setCurrentItem(viewpager.getCurrentItem() + 1);//收到消息,指向下一个页面 handler.sendEmptyMessageDelayed(msgWhat, 2000);//2S后在发送一条消息,由于在handleMessage()方法中,造成死循环。 Log.d(tag, "handleMessage"); }; };
同时在onCreat()方法中发送消息:handler.sendEmptyMessageDelayed(msgWhat, 2000);
出现的bug
Bug1:内存泄露
Bug:虽然我们实现了 无限自动循环功能,但当我们由MainActivity调转到SecondActivity的时候,通过Log.d(tag, “handleMessage”);发现handler还在发送消息,这就是内存泄露,所以我们需要在ManiActivity不可见不可交互的时候移除message。解决方法:在onStop()里移除message
/** * 当MainActivity不可见的时候让handler停止发送消息 * 防止内存泄露 */ @Override protected void onStop() { super.onStop(); handler.removeMessages(msgWhat); }
Bug2:再次回到 当前页,viewpager不再自动循环
由于我们把handler.sendEmptyMessageDelayed(msgWhat, 2000);写在了onCreate(),当我们由MainActivity调转到SecondActivity的时候,在回来MainActivity的时候,MainActivity并没有被销毁,onCreate()方法并不会再执行。解决方法:写在onResume()里面
/** * activity可见可交互的时候就开始发送消息,开启循环 */ @Override protected void onResume() { super.onResume(); handler.sendEmptyMessageDelayed(msgWhat, 2000); }
所以,最后的完整代码是:
public class MainActivity extends Activity {
protected static final String tag = "MainActivity";
private ViewPager viewpager;
private List<ImageView> imageList = new ArrayList<ImageView>();
private Context context;
int msgWhat = 0; private Handler handler = new Handler(){ public void handleMessage(android.os.Message msg) { viewpager.setCurrentItem(viewpager.getCurrentItem() + 1);//收到消息,指向下一个页面 handler.sendEmptyMessageDelayed(msgWhat, 2000);//2S后在发送一条消息,由于在handleMessage()方法中,造成死循环。 Log.d(tag, "handleMessage"); }; };
private Button btn;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
context = this;
initData();
viewpager = (ViewPager) findViewById(R.id.viewpager);
viewpager.setAdapter(new MyAdapter());
viewpager.setCurrentItem(1000);//当前页是第1000页
// Button只是为了验证内存泄露
btn = (Button) findViewById(R.id.btn);
btn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(context, SecondActivity.class);
startActivity(intent);
}
});
}
private void initData() {
imageList.clear();
ImageView iva = new ImageView(context);
iva.setBackgroundResource(R.drawable.a);
ImageView ivb = new ImageView(context);
ivb.setBackgroundResource(R.drawable.b);
ImageView ivc = new ImageView(context);
ivc.setBackgroundResource(R.drawable.c);
ImageView ivd = new ImageView(context);
ivd.setBackgroundResource(R.drawable.d);
ImageView ive = new ImageView(context);
ive.setBackgroundResource(R.drawable.e);
imageList.add(iva);
imageList.add(ivb);
imageList.add(ivc);
imageList.add(ivd);
imageList.add(ive);
}
public class MyAdapter extends PagerAdapter{
//表示viewpager共存放了多少个页面 @Override public int getCount() { return Integer.MAX_VALUE;//我们设置viewpager中有Integer.MAX_VALUE个页面 }
@Override
public boolean isViewFromObject(View view, Object object) {
return view == object;
}
/** * position % imageList.size() 而不是position,是为了防止角标越界异常 * 因为我们设置了viewpager子页面的数量有Integer.MAX_VALUE,而imageList的数量只是5。 */ @Override public Object instantiateItem(ViewGroup container, int position) { container.addView(imageList.get(position % imageList.size())); return imageList.get(position % imageList.size()); }
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((View)object);
}
}
/** * activity可见可交互的时候就开始发送消息,开启循环 */ @Override protected void onResume() { super.onResume(); handler.sendEmptyMessageDelayed(msgWhat, 2000); }
/** * 当MainActivity不可见的时候让handler停止发送消息 * 防止内存泄露 */ @Override protected void onStop() { super.onStop(); handler.removeMessages(msgWhat); }
}
也可以不使用`Integer.MAX_VALUE`,还是以前的
@Override
public int getCount() {
return imgsList.size();
// return Integer.MAX_VALUE;
}
``` int index = (viewPager.getCurrentItem() + 1) % imgsList.size(); viewPager.setCurrentItem(index);
“`
源码
ViewPager无线自动循环这样我们就实现了viewpager的自动无限循环功能,而且手动向左滑、向右滑都可以,接下来我们添加indicator。
Android中级:轮播图(二):实现indicator。地址:http://blog.csdn.net/ss1168805219/article/details/52294657
相关文章推荐
- Android使用ViewPager实现图片轮播(高度自适应,左右循环,自动轮播)
- Android之ViewPager自动循环播放(轮播)效果实现(超简单)
- Android实现基于ViewPager的无限循环自动播放带指示器的轮播图CarouselFigureView控件
- Android无限循环与自动播放ViewPager的简单实现(广告栏)
- Android使用ViewPager实现左右循环滑动及轮播效果
- Android 使用ViewPager实现左右循环滑动及轮播效果
- Android 使用ViewPager实现左右循环滑动及轮播效果
- android ViewPager实现自动无限轮播和下方向导圆点
- Android使用ViewPager实现左右循环滑动及轮播效果
- ViewPager 实现自动循环轮播 高度自适应 显示前后部分界面 点击事件
- Android ViewPager实现无限循环轮播广告位Banner效果
- Android实现viewpager实现循环轮播效果
- Android使用viewpager实现自动无限轮播图
- Android使用ViewPager实现无限循环滑动及轮播(附源代码)
- Android_viewpager无线+自动轮播
- Android ViewPager的无限循环与自动滚动实现
- Android ViewPager巧用偷梁换柱实现自动循环滚动
- Android使用ViewPager实现左右循环滑动及轮播效果
- Android使用ViewPager实现左右循环滑动及轮播效果
- Android使用ViewPager实现无限循环滑动及轮播(附源码)