ViewPager基础
# 1. ViewPager简介
ViewPager是Android扩展包v4包中的类
android.support.v4.view.ViewPager
类似于LinearLayout,ViewPager类直接继承了ViewGroup类,是一个容器,需要在里面添加我们想要显示的内容。
类似于ListView,ViewPager类需要PagerAdapter适配器类提供数据。
# 2. PagerAdapter的使用
使用这个PagerAdapter需要重写下面的四个方法: 当然,这只是官方建议,实际上我们只需重写getCount()
和 isViewFromObject()
就可以了~
getCount(): 获得ViewPager中有多少个view
destroyItem(): 从当前container中删除指定位置(position)的View。
适配器有责任从容器中删除这个视图。 这是为了确保在finishUpdate
(ViewGroup)返回时视图能够被移除。
instantiateItem():
将当前视图添加到container中
返回当前View
- 给定位置的view添加到ViewGroup(容器)中,创建并显示出来
- 返回一个代表新增页面的Object(key),通常都是直接返回view本身就可以了;当然你也可以自定义自己的key,但是key和每个view要一一对应的关系
isViewFromObject():
判断instantiateItem
(ViewGroup, int)函数所返回来的Key与一个页面视图是否是代表的同一个视图(即它俩是否是对应的,对应的表示同一个View),通常我们直接写 return view == object
# 3. ViewPager导航页实例
# 1. 基础实现
三步走:
- 新建ViewPager
- 创建适配器
- 设置数据适配器
# 1.1 新建ViewPager视图
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.viewpager.widget.ViewPager
android:id="@+id/view_pager"
android:layout_width="match_parent"
android:layout_height="match_parent"></androidx.viewpager.widget.ViewPager>
<!--添加一个线性布局,用于存放导航点-->
<LinearLayout
android:id="@+id/layout"
android:layout_width="match_parent"
android:layout_height="200dp"
android:layout_marginTop="600dp"
android:gravity="center"
android:orientation="horizontal" />
</FrameLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# 1.2 创建适配器
为了简便,Adapter直接放到了MainAcitivty的内部类中
private class MyPagerAdapter extends PagerAdapter {
@Override
public int getCount() {
return data.length;
}
@Override
public boolean isViewFromObject(@NonNull @NotNull View view, @NonNull @NotNull 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));
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# 1.3 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);
}
2
3
4
5
6
7
8
9
10
11
12
13
# 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
3
4
5
6
7
8
# 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
4
5
6
7
8
9
10
11
# 2.3 设置addOnPageChangeListener监听器
private void setListener() {
mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
/**
* 当页面滚动了触发
* @param position
* @param positionOffset
* @param positionOffsetPixels
*/
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
for (int i = 0; i < data.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) {
// 配置当手动滑动的时候,停止自动滑动
if (state == ViewPager.SCROLL_STATE_DRAGGING) {
handler.removeCallbacksAndMessages(null);
}
// 当空闲时,会再次开始自动滑动
if (state == ViewPager.SCROLL_STATE_IDLE) {
// 清空消息队列
handler.removeCallbacksAndMessages(null);
handler.sendEmptyMessageDelayed(1, 2000);
}
}
});
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# 2.4 设置导航点的间隙
设置导航点的左右间隙,可以通过下面的代码来实现。
// 加载导航点
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);
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 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);
}
};
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
之后,只要再onCreate的时候,调用一次就可以了。
handler.sendEmptyMessageDelayed(1,2000);
# 4. 手动滑动的时候,停止自动滑动
需要在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);
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 4. ViewPager参数设置
private fun initPagerView() {
mViewPager.pageMargin = 20 // 设置页面之间的边距
mViewPager.offscreenPageLimit = mList.size // 设置在空闲状态下视图层次结构中应保留到当前页面任一侧的页面数。 超出此限制的页面将在需要时从适配器重新创建。
mViewPager.adapter = BasePagerAdapter(mListView)
mViewPager.setPageTransformer(true, ScaleInTransformer()) // 设置偏移量
}
2
3
4
5
6