1、 布局
<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"
tools:context=".MainActivity" >
<android.support.v4.view.ViewPager
android:id="@+id/view_pager"
android:layout_width="match_parent"
android:layout_height="150dp"/>
</RelativeLayout>
2、Java代码:
public class MainActivity extends Activity {
private int[] imageResIds = {
R.drawable.a,
R.drawable.b,
R.drawable.c,
R.drawable.d,
R.drawable.e,
};
private String[] descs = {
"巩俐不低俗,我就不能低俗",
"扑树又回来啦!再唱经典老歌引万人大合唱",
"揭秘北京电影如何升级",
"乐视网TV版大派送",
"热血屌丝的反杀",
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ViewPager viewPager = (ViewPager) findViewById(R.id.view_pager);
viewPager.setAdapter(new BannerAdpater(imageResIds));
}
}
ViewPager的使用跟ListView类似,都需要一个适配器,但是ViewPager必要的是PagerAdapter,如下:
public class BannerAdpater extends PagerAdapter {
private int[] imageResIds;
public BannerAdpater(int[] imageResIds) {
this.imageResIds = imageResIds;
}
public int getCount() {
return imageResIds.length;
}
public boolean isViewFromObject(View view, Object object) {
return view == object;
}
public Object instantiateItem(ViewGroup container, int position) {
ImageView imageView = new ImageView(container.getContext());
imageView.setBackgroundResource(imageResIds[position]);
container.addView(imageView);
return imageView;
}
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((View) object);
}
3、ViewPager生成界面和销毁界面原理
l 判断屏幕显示的是否是0位置,如果不是说明左边要有界面,调用isViewFromObject判断左边是否已存在界面,如不存在则调用instantiateItem方法来生成界面
l 判断屏幕显示的是否是getCount - 1位置,如果不是说明右边要有界面,调用isViewFromObject判断左边是否已存在界面,如不存在则调用instantiateItem方法来生成界面
l 超出范围的界面调用destroyItem销毁
4、与ViewPager界面对应的描述和点
修改布局,如下:
<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"
tools:context=".MainActivity" >
<android.support.v4.view.ViewPager
android:id="@+id/view_pager"
android:layout_width="match_parent"
android:layout_height="150dp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignBottom="@id/view_pager"
android:background="@color/trans_black"
android:gravity="center"
android:orientation="vertical"
android:padding="6dp" >
<TextView
android:id="@+id/tv_desc"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="中华人民共和国中华人民共和国"
android:textColor="@android:color/white" />
<LinearLayout
android:id="@+id/ll_dots"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginTop="6dp" />
</LinearLayout>
</RelativeLayout>
ViewPager对应的点是不能在布局中写死的,需要通过Java代码动态创建,如下:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ViewPager viewPager = (ViewPager) findViewById(R.id.view_pager);
viewPager.setAdapter(new BannerAdpater(imageResIds));
ll_dots = (LinearLayout) findViewById(R.id.ll_dots);
tv_desc = (TextView) findViewById(R.id.tv_desc);
initDots();
}
private void initDots() {
for (int i = 0; i < imageResIds.length; i++) {
View dot = new View(this);
dot.setBackgroundResource(R.drawable.selector_dot);
LayoutParams params = new LayoutParams(5, 5);
params.leftMargin = i == 0 ? 0: 5; // 如果是第0个点,不需要设置leftMargin
dot.setLayoutParams(params); // 设置dot的layout参数
ll_dots.addView(dot); // 把dot添加到线性布局中
}
}
默认显示第1张图片的描述和选中第1个点,代码如下:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 。。。之前的代码
initDots();
changeDescAndDot(0);
}
private void changeDescAndDot(int position) {
// 显示position位置的文字描述
tv_desc.setText(descs[position]);
// 把position位置的点设置为selected状态
for (int i = 0; i < ll_dots.getChildCount(); i++) {
ll_dots.getChildAt(i).setSelected(i == position);
}
}
通过监听ViewPager页面的改变去动态改变文字描述和选择的点,代码如下:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 。。。之前的代码
viewPager.setOnPageChangeListener(mOnPageChangeListener);
}
/** ViewPager页面改变监听器 */
OnPageChangeListener mOnPageChangeListener = new OnPageChangeListener() {
// 当页面被选择
@Override
public void onPageSelected(int position) {
changeDescAndDot(position);
}
// 当页面滚动
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
// 当页面的滚动状态发生改变
@Override
public void onPageScrollStateChanged(int state) {
}
};
5、实现无限循环
实现无限循环步骤:
1、在getCount方法返回一个比较大的页数:imageSize * 10000 * 100;
2、在所有使用position的地方(instantiateItem、onPageSelected)先对这个position取余:position = position % imageSize;,取余之后再使用position,确保position不会导致脚标越界,取余结果分析如下:
// 让position在0 ~ (imageSize – 1)之间进行循环,则把position %imageSize即可,如下:
// 假如imageSize = 5,则取余情况如下:
// 0 % 5 = 0;
// 1 % 5 = 1;
// 2 % 5 = 2;
// 3 % 5 = 3;
// 4 % 5 = 4;
// 5 % 5 = 0;
// 6 % 5 = 1;
// 7 % 5 = 2;
// ...
3、初始化ViewPager的时候就让ViewPager显示到页数一半的地方: viewPager.setCurrentItem(viewPager.getAdapter().getCount() / 2);
6、自动切换ViewPager
切换到下一页:取出当前界面的索引,把索引加加,然后跳转到这个加加之后的索引
定时切换:使用Handler循环的发延迟消息,可实现定时器的效果,不停调用上面的切换到下一页的方法即可。
实现代码:
1、自动切换,就是自动的显示下一页,提供一个显示下一页的方法,如下
public void showNextPage() {
viewPager.setCurrentItem(viewPager.getCurrentItem() + 1);
}
2、什么时候开始显示下一页呢?当ViewPager显示的时候再过3秒钟就要显示下一页,所以可以使用Handler发延迟消息,如下:
/** 显示下一页 */
public static final int SHOW_NEXT_PAGE = 0;
private Handler handler = new Handler() {
public void handleMessage(Message msg) {
switch (msg.what) {
case SHOW_NEXT_PAGE:
showNextPage();
break;
}
}
};
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 。。。 以前的代码
viewPager.setCurrentItem(viewPager.getAdapter().getCount() / 2);
handler.sendEmptyMessageDelayed(SHOW_NEXT_PAGE, 3000);
}
3、上面只是实现了一切的切换,要想实现不停地自动切换到下一页,重复调用handler发消息即可,如下:
public void showNextPage() {
viewPager.setCurrentItem(viewPager.getCurrentItem() + 1);
handler.sendEmptyMessageDelayed(SHOW_NEXT_PAGE, 3000);
}