ViewPager实现翻页效果&导航点
0. 效果演示
1. 基础实现
三步走:
0.新建ViewPager
1.创建适配器
2.设置数据适配器
1.1 新建ViewPager视图
1.2 创建适配器
private class myAdapter extends PagerAdapter {
// 这四个方法需要被重写
@Override
public int getCount() {
return wxs.length;
}
@Override
public boolean isViewFromObject(@NonNull View view, @NonNull Object object) {
return view == object;
}
@NonNull
@Override
public Object instantiateItem(@NonNull ViewGroup container, int position) {
// 1. 将数据添加到布局文件中
container.addView(list.get(position));
// 2. 数据返回
return list.get(position);
}
@Override
public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
// 移除划过的的视图
container.removeView(list.get(position));
}
}
1.3 绑定数据到适配器
ViewPager vp = (ViewPager) findViewById(R.id.vp);
vp.setAdapter(new myAdapter());
备注:ViewPager中存放视图。
List<ImageView> list = new ArrayList<>();
for (int wx : wxs) {
ImageView imageView = new ImageView(mContext);
// setBackgroundResource 会自动填充满父容器
imageView.setBackgroundResource(wx);
// imageView.setImageResource(wx);
// setImageResource不会
// 添加到视图中
list.add(imageView);
}
对,使用ViewPager就这么简单,这样图1的翻页效果就实现了。
2. 代码优化(添加导航点)
上面的代码是实现了手势换页,但是导航点还有没有实现。
步骤:
- 创建xml文件(导航点)
- 加载导航点
- 设置addOnPageChangeListener监听器
2.1 创建导航点
首先,我们要在drawable文件中创建导航点,就是手动画一个。
drawble 右击新建 — > new Reasouse xml
page_off.xml创建过程,与之类似。
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<solid android:color="#ddd" />
<size
android:width="10dp"
android:height="10dp" />
</shape>
2.2 加载导航点
首先在布局文件中,添加一个线性布局,用于存放导航点
然后在MainActivity中运行这段代码。
mContext = MainActivity.this;
layout = (LinearLayout) findViewById(R.id.layout);
// 加载导航点
for (int i = 0; i < wxs.length; i++) {
ImageView imageView = new ImageView(mContext);
imageView.setImageResource(R.drawable.page_off);
// layout指的是线性布局文件
layout.addView(imageView);
}
2.3 设置addOnPageChangeListener监听器
// 需要重写页面切换事件(添加下标点)
vp.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
// 当页面滚动了触发
for (int i = 0; i < wxs.length; i++) {
ImageView imageView = (ImageView) layout.getChildAt(i);
if (i == position) {
// 点亮
imageView.setImageResource(R.drawable.page_on);
} else {
imageView.setImageResource(R.drawable.page_off);
}
}
}
@Override
public void onPageSelected(int position) {
}
@Override
public void onPageScrollStateChanged(int state) {
}
});
2.4 运行效果
3. 添加自动换页机制
通过添加handler来进行自动换页。
Handler handler = new Handler(){
@Override
public void handleMessage(@NonNull Message msg) {
// 添加处理消息通知的代码
if (msg.what == 1){
// 如何到了最后一页,就跳转回第一页
if (vp.getCurrentItem() == wxs.length-1){
vp.setCurrentItem(0);
}else{
// 跳转到下一页内容
vp.setCurrentItem(vp.getCurrentItem()+1);
}
}
handler.sendEmptyMessageDelayed(1,2000);
}
};
之后,只要再onCreate的时候,调用一次就可以了。
handler.sendEmptyMessageDelayed(1,2000);
运行效果:
整个过程中,我手没有进行任何操作,全部是它自动完成的换页。
但是,这个体验并不好,我们应该当手动滑动的时候,停止自动滑动。
需要在addOnPageChangeListener 里面的onPageScrollStateChanged添加以下代码:
@Override
public void onPageScrollStateChanged(int state) {
// 配置当手动滑动的时候,停止自动滑动
if (state == ViewPager.SCROLL_STATE_DRAGGING){
handler.removeCallbacksAndMessages(null);
}
// 当空闲时,会再次开始自动滑动
if (state == ViewPager.SCROLL_STATE_IDLE){
// 清空消息队列
handler.removeCallbacksAndMessages(null);
handler.sendEmptyMessageDelayed(1,2000);
}
}
此时,当我们进行手动滑动的时候,自动滑动就会停止。
补充:设置导航点的左右间隙,可以通过下面的代码来实现。
// 加载导航点
for (int i = 0; i < wxs.length; i++) {
ImageView imageView = new ImageView(mContext);
imageView.setImageResource(R.drawable.page_off);
// 必须通过 LinearLayout.LayoutParams
LinearLayout.LayoutParams lp = new
LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT);
//设置小圆点的间距
lp.setMargins(4, 0, 4, 0);
layout.addView(imageView, lp);
}