icode icode
首页
  • Android学习

    • 📁基础内容
    • 📺AndroidCore
    • 🎨Android-UI
    • 🏖️Components
    • 📊Fragment
    • 🔗网络操作
    • 🔏异步机制
    • 📦数据存储
    • 🗃️Gradle
  • 学习笔记

    • 『框架』笔记
    • 『Kotlin』笔记
    • 《Vue》笔记
    • 《Git》学习笔记
    • 『Bug踩坑记录』
  • ListView
  • RecyclerView
  • ViewPager
  • Java笔记

    • 🟠JavaSE
    • 🟢JavaWeb
    • 🔴JavaEE
    • ⚪JavaTopic
    • 🍳设计模式
  • 计算机基础

    • 📌计算机网络
    • 🔍数据结构
    • 📦数据库
    • 💻OS
  • 技术文档
  • GitHub技巧
  • Nodejs
  • 博客搭建
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 友情链接
  • 关于

    • 📫关于我
  • 收藏

    • 网站
    • 资源
    • Vue资源
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

iqqcode

保持对技术的探索实践与热爱
首页
  • Android学习

    • 📁基础内容
    • 📺AndroidCore
    • 🎨Android-UI
    • 🏖️Components
    • 📊Fragment
    • 🔗网络操作
    • 🔏异步机制
    • 📦数据存储
    • 🗃️Gradle
  • 学习笔记

    • 『框架』笔记
    • 『Kotlin』笔记
    • 《Vue》笔记
    • 《Git》学习笔记
    • 『Bug踩坑记录』
  • ListView
  • RecyclerView
  • ViewPager
  • Java笔记

    • 🟠JavaSE
    • 🟢JavaWeb
    • 🔴JavaEE
    • ⚪JavaTopic
    • 🍳设计模式
  • 计算机基础

    • 📌计算机网络
    • 🔍数据结构
    • 📦数据库
    • 💻OS
  • 技术文档
  • GitHub技巧
  • Nodejs
  • 博客搭建
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 友情链接
  • 关于

    • 📫关于我
  • 收藏

    • 网站
    • 资源
    • Vue资源
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • ListView

  • RecyclerView

  • ViewPager

    • ViewPager基础
      • 1. ViewPager简介
      • 2. PagerAdapter的使用
      • 3. ViewPager导航页实例
        • 1. 基础实现
        • 2. 添加导航点
        • 3. 添加自动换页机制
        • 4. 手动滑动的时候,停止自动滑动
      • 4. ViewPager参数设置
      • 5. ViewPager避免OOM
    • 用ViewPager偏移看到下一页部分内容
    • 结合TabLayout使用
    • ViewPager注意事项
    • androidclipChildren属性
  • Component
  • ViewPager
iqqcode
2021-06-02
目录

ViewPager基础

# 1. ViewPager简介

ViewPager是Android扩展包v4包中的类

android.support.v4.view.ViewPager
1
  • 类似于LinearLayout,ViewPager类直接继承了ViewGroup类,是一个容器,需要在里面添加我们想要显示的内容。

  • 类似于ListView,ViewPager类需要PagerAdapter适配器类提供数据。


# 2. PagerAdapter的使用

使用这个PagerAdapter需要重写下面的四个方法: 当然,这只是官方建议,实际上我们只需重写getCount() 和 isViewFromObject()就可以了~

getCount(): 获得ViewPager中有多少个view


destroyItem(): 从当前container中删除指定位置(position)的View。

适配器有责任从容器中删除这个视图。 这是为了确保在finishUpdate(ViewGroup)返回时视图能够被移除。


instantiateItem():

  1. 将当前视图添加到container中

  2. 返回当前View

  • 给定位置的view添加到ViewGroup(容器)中,创建并显示出来
  • 返回一个代表新增页面的Object(key),通常都是直接返回view本身就可以了;当然你也可以自定义自己的key,但是key和每个view要一一对应的关系

isViewFromObject():

判断instantiateItem(ViewGroup, int)函数所返回来的Key与一个页面视图是否是代表的同一个视图(即它俩是否是对应的,对应的表示同一个View),通常我们直接写 return view == object



# 3. ViewPager导航页实例

image-20210508082806984

# 1. 基础实现

三步走:

  1. 新建ViewPager
  2. 创建适配器
  3. 设置数据适配器

# 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>
1
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));
        }

    }
1
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);
}

1
2
3
4
5
6
7
8
9
10
11
12
13

# 2. 添加导航点

步骤:

  1. 创建xml文件(导航点)
  2. 加载导航点
  3. 设置addOnPageChangeListener监听器

# 2.1 创建导航点

首先,我们要在drawable文件中创建导航点,就是手动画一个。

drawble 右击新建 — > new Reasouse xml

img

img

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>
1
2
3
4
5
6
7
8

# 2.2 加载导航点

首先在布局文件中,添加一个线性布局,用于存放导航点

image-20210508083310049

然后在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);
}

1
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);
                }
            }
        });
    }
1
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);
}

1
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);
    }
};

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

之后,只要再onCreate的时候,调用一次就可以了。

handler.sendEmptyMessageDelayed(1,2000);
1

# 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);
    }
}
1
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()) // 设置偏移量
}
1
2
3
4
5
6

# 5. ViewPager避免OOM

编辑 (opens new window)
上次更新: 2021/06/02, 10:01:48
RecyclerView缓存复用机制
用ViewPager偏移看到下一页部分内容

← RecyclerView缓存复用机制 用ViewPager偏移看到下一页部分内容→

最近更新
01
匿名内部类
10-08
02
函数式接口
10-08
03
ARouter-Kotlin踩坑
10-05
更多文章>
Theme by Vdoing | Copyright © 2021-2023 iqqcode | MIT License | 备案号-京ICP备2021028793号
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式
×