ViewPager详解(二)广告轮播图
效果图
一、ViewPager填充图片
1.1 布局中申明
由于是显示广告条,所以高度要固定住
<android.support.v4.view.ViewPager android:id="@+id/viewpager" android:layout_width="match_parent" android:layout_height="120dp"/>
1.2 代码中设置页面数据
准备显示图片控件的集合
// 准备显示的图片集合 mList = new ArrayList<>(); for (int i = 0; i < mImages.length; i++) { ImageView imageView = new ImageView(this); // 将图片设置到ImageView控件上 imageView.setImageResource(mImages[i]); // 将ImageView控件添加到集合 mList.add(imageView); }
自定义类书写适配器
@Override public Object instantiateItem(ViewGroup container, int position) { // return super.instantiateItem(container, position); // 将图片控件添加到容器 container.addView(mList.get(position)); // 返回 return mList.get(position); }
二、底部小圆点显示逻辑
原理分析:底部的小圆点时浮动在ViewPager上面的的,所以应该是一个RelativeLayout布局。
ViewPager页面切换时小圆点的颜色不一样,所以需要对小圆点做选择器,并且对ViewPager进行监听。
2.1 布局申明
需要用一个RelativeLayout将ViewPager和包裹圆点的LinearLayout包裹起来
<RelativeLayout android:layout_width="match_parent" android:layout_height="120dp"> <android.support.v4.view.ViewPager android:id="@+id/viewpager" android:layout_width="match_parent" android:layout_height="120dp"/> <LinearLayout android:id="@+id/pointgroup" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_centerHorizontal="true" android:layout_marginBottom="3dp" android:orientation="horizontal"> </LinearLayout> </RelativeLayout>
2.2 制作小圆点颜色选择器
选择器的选中状态应该设置为selected,因为对ViewPager监听时可以设置selected的属性
<selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:drawable="@drawable/shape_point_normal" android:state_selected="false"/> <item android:drawable="@drawable/shape_point_selected" android:state_selected="true"/> </selector> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval"> <solid android:color="#66000000"/> </shape <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval"> <solid android:color="#FFFFFF"/> </shape>
2.3 将小圆点添加到LinearLayout容器
- 小圆点其实就是一个ImageView,所以在做出ViewPager的页面图片时,一起把小圆点也做了
初始化ImageView添加到LinearLayout之前,需要设置小圆点的布局参数,包括位置和大小
LinearLayout pointGroup = (LinearLayout) findViewById(R.id.pointgroup); for (int i = 0; i < mImages.length; i++) { // 制作底部小圆点 ImageView pointImage = new ImageView(this); pointImage.setImageResource(R.drawable.shape_point_selector); // 设置小圆点的布局参数 int PointSize = getResources().getDimensionPixelSize(R.dimen.point_size); LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(PointSize, PointSize); if (i > 0) { params.leftMargin = getResources().getDimensionPixelSize(R.dimen.point_margin); pointImage.setSelected(false); } else { pointImage.setSelected(true); } pointImage.setLayoutParams(params); // 添加到容器里 pointGroup.addView(pointImage); }
三、小圆点随着ViewPager切换移动
其实就是对ViewPager设置滑动监听,当滑动到每一页时就设置小圆点为选中状态,这样小圆点就显示白色,其他页面就设置为未选中状态显示灰色。
// 对ViewPager设置滑动监听 viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { } int lastPosition; @Override public void onPageSelected(int position) { // 页面被选中 // 设置当前页面选中 pointGroup.getChildAt(position).setSelected(true); // 设置前一页不选中 pointGroup.getChildAt(lastPosition).setSelected(false); // 替换位置 lastPosition = position; } @Override public void onPageScrollStateChanged(int state) { } });
- 这里设置选中和未选中除了可以用替换position的方法之外,还可以再定义一个ImageView来记录选中的ImageView,然后在监听里替换,思想都是一样的。
经过前面的三步设置后就能显示一个简单的广告条了,这里再对其添加一个滑动到最后一页后再滑还能滑动到首页的功能。
四、无限滑动的ViewPager
实现原理: ViewPager之所以滑动到左右能显示页面,其实是因为左右都存在即将要显示的页面。当左右有很多页面时我们就能一直滑动,没有时就不能滑动。所以原理就是让ViewPager的左右都有很多的页面。
4.1 修改getCount方法
ViewPager能显示多少个页面全由getCount方法说了算,所以我们首先要改造它。
@Override public int getCount() { // 返回整数的最大值 return Integer.MAX_VALUE; }
4.2 修改instantiateItem方法
因为position变了,所以显示的位置也变了,这里需要进行取%运算,来还原position。
// 修改position position = position % mList.size();
4.3 修改ViewPager监听器里的onPageSelected
用到了position就要修改。
position = position % mList.size();
修改之后,ViewPager当前页的右边就有了无数的页面,但是因为%了mList.size(),就只会显示mList.size()的大小,这样就实现了无限滑动轮播
五、无限自动轮播的广告图
实现原理:在前面四步的基础上,在代码里添加一个Handler,不断的给自己发消息就好了。
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
int currentPosition = viewPager.getCurrentItem();
if(currentPosition == viewPager.getAdapter().getCount() - 1){
// 最后一页
viewPager.setCurrentItem(0);
}else{
viewPager.setCurrentItem(currentPosition + 1);
}
// 一直给自己发消息
mHandler.postDelayed(this,5000);
}
},5000);