ViewPager学习
项目需求,想要实现一个轮播的广告页,于是使用VIewPager来实现,首先来看下PagerAdapter。
1.PagerAdapter
PagerAdapter为一个抽象类,导包如下:
import android.support.v4.view.PagerAdapter;
在使用PagerAdapter时,需要自定义类继承自PagerAdapter,同时,需要实现以下四个方法:
@Override //此方法返回可获得的View数量 public int getCount() { return 0; } @Override //用来判断instantiateItem方法返回的Object是否要和当前页面关联 public boolean isViewFromObject(View view, Object object) { return false; } @Override //移除position处的view,将view从container中移除 public void destroyItem(ViewGroup container, int position, Object object) { super.destroyItem(container, position, object); } @Override //创建position位置处的view,同时需要手动添加到container中 public Object instantiateItem(ViewGroup container, int position) { return super.instantiateItem(container, position); }
示例使用如下:
public class ViewPagerAdapter extends PagerAdapter { private List<ImageView> views; public ViewPagerAdapter(List<ImageView> views) { this.views = views; } @Override public int getCount() { return views == null ? 0 : views.size(); } @Override public boolean isViewFromObject(View view, Object object) { return view == object; } @Override public void destroyItem(ViewGroup container, int position, Object object) { if (views != null) { View view = views.get(position); container.removeView(view); } } @Override public Object instantiateItem(ViewGroup container, int position) { if (views != null) { View view = views.get(position); if (view != null) { container.addView(view); return view; } } return null; } }
2.实现轮播
采用Handler+ViewPager来实现定时播放,同时使用LinearLayout来实现圆点指示器
a.布局如下:
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <android.support.v4.view.ViewPager android:id="@+id/viewPager" android:layout_width="match_parent" android:layout_height="match_parent" /> <LinearLayout android:id="@+id/indicator" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_marginBottom="10dp" android:gravity="center_horizontal" android:orientation="horizontal" android:padding="5dp" /> </RelativeLayout>
b.圆点指示器
如上面的布局文件所示,采用LinearLayout来定制圆点指示器,当只有一张图片时,不显示圆点指示器,圆点采用Shape绘制而成,主要有正常状态的圆点和被选中的圆点:
(1).正常圆点
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval" android:useLevel="false"> <solid android:color="#fff" /> <size android:width="10dp" android:height="10dp" /> </shape>
(2).选中状态的圆点
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval" android:useLevel="false"> <!-- 圆的大小,要保证长和宽一样大 --> <size android:width="10dp" android:height="10dp" /> <!-- 中间填充的颜色 --> <solid android:color="#000" /> <!-- 边框大小及颜色 --> <stroke android:width="1dp" android:color="#fff" /> </shape>
使用时,根据List中ImageView的数量添加圆点,当List的大小为1时,隐藏圆点指示器,添加圆点指示器的代码如下:
private void initIndicator() { //mIndicator布局中的LinearLayout mIndicator.removeAllViews(); if (mImages != null && mImages.size() > 1) { mIndicator.setVisibility(View.VISIBLE); } else { mIndicator.setVisibility(View.GONE); } for (int i = 0; i < mImages.size(); i++) { ImageView imageView = new ImageView(SplashActivity.this); if (i == 0) { imageView.setBackgroundResource(R.drawable.point_selected); } else { imageView.setBackgroundResource(R.drawable.point_normal); } mIndicator.addView(imageView); } }
同时,ViewPager中的页面改变时,需要改变圆点状态,方法如下:
private void changePoint(int position) { //mPrePosition标识页面变换之前的位置 if (mPrePosition != position) { ImageView prePoint = (ImageView) mIndicator.getChildAt(mPrePosition); ImageView mCurPoint = (ImageView) mIndicator.getChildAt(position); if (prePoint != null && mCurPoint != null) { prePoint.setBackgroundResource(R.drawable.point_normal); mCurPoint.setBackgroundResource(R.drawable.point_selected); mPrePosition = position; } } }
c.示例代码如下:
//示例数据,初始化要显示的图片***************************************** mImages = new ArrayList<ImageView>(); ImageView imageView1 = new ImageView(SplashActivity.this); imageView1.setBackgroundResource(R.drawable.default_imageload_pic); mImages.add(imageView1); ImageView imageView2 = new ImageView(SplashActivity.this); imageView2.setBackgroundResource(R.drawable.default_imageload_pic); mImages.add(imageView2); ImageView imageView3 = new ImageView(SplashActivity.this); imageView3.setBackgroundResource(R.drawable.default_imageload_pic); mImages.add(imageView3); //********************************************************************* mAdapter = new ViewPagerAdapter(mImages); mViewPager.setAdapter(mAdapter);
设置监听页面变化,需要在页面被选中时,改变圆点指示器的状态:
mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { } @Override public void onPageSelected(int position) { //改变圆点指示器的位置 changePoint(position); } @Override public void onPageScrollStateChanged(int state) { } });
当用户手动滑动图片时,停止自动滑动,设置一个标志位即可。
mViewPager.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { autoChange = false; return false; } });
使用Handler自动翻页,示例代码如下:
private Handler mHanlder = new Handler() { @Override public void handleMessage(Message msg) { switch (msg.what) { case MSG_CHANGE: if (autoChange) { changeImage(mPrePosition + 1); mHanlder.sendEmptyMessageDelayed(MSG_CHANGE, INTERVAL); } break; } } }; mHanlder.sendEmptyMessageDelayed(MSG_CHANGE, INTERVAL); //翻页 private void changeImage(int position) { if (mPrePosition != position) { if (mImages != null) { if (position >= mImages.size()) { position = 0; } mViewPager.setCurrentItem(position); } } }
注意:
为了避免Handler造成的内存泄漏,需要在onDestory方法里面remove掉所有消息,并且销毁Handler,方法如下:
@Override protected void onDestroy() { super.onDestroy(); mHanlder.removeCallbacksAndMessages(null); mHanlder = null; }