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基础
    • 用ViewPager偏移看到下一页部分内容
      • 【Android实战】用ViewPager偏移看到下一页部分内容
      • 1.准备工作
      • 2.用PageTransformer来改变ViewPager的切换动画
      • 3.通过setOffscreenPageLimit(int limit)来改变缓存页数
      • 4.彩蛋
    • 结合TabLayout使用
    • ViewPager注意事项
    • androidclipChildren属性
  • Component
  • ViewPager
iqqcode
2021-06-02
目录

用ViewPager偏移看到下一页部分内容

# 【Android实战】用ViewPager偏移看到下一页部分内容

http://www.voidcn.com/article/p-zhcdoykj-xn.html

机顶盒项目有个需求,在TV选项下,要求第一页显示节目时,能看到第二页部分内容(也就是图中最右边有黑色遮罩层的那些是第二页的内容):

这里写图片描述

当向右翻页时,第二页的内容滑到最左边,且第三页的部分内容显示在最右边。

这里写图片描述


这个项目我是用ViewPager实现滑页的,现在来针对上面的需求进行讲解如何实现。


# 1.准备工作

为此我新建了个简单的项目,用一个ViewPager包裹4个View,每个View给它一个不一样的背景色,并给ViewPager加上适配器(Adapter)。

准备工作就做好了(以下基础代码可跳过)

public void init() {
        ViewPager viewPager = (ViewPager) findViewById(R.id.viewpager);
        View v1 = new View(this);
        View v2 = new View(this);
        View v3 = new View(this);
        View v4 = new View(this);
        v1.setBackgroundColor(Color.parseColor("#aaabcdef"));
        v2.setBackgroundColor(Color.parseColor("#aa000a00"));
        v3.setBackgroundColor(Color.parseColor("#aaabc000"));
        v4.setBackgroundColor(Color.parseColor("#aa000000"));

        List<View> views = new ArrayList<View>();
        views.add(v1);
        views.add(v2);
        views.add(v3);
        views.add(v4);

        viewPager.setAdapter(new AZPagerAdapter(views));
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

AZPagerAdapter的实现是比较常规的优化方法:“显示”就把View加载到父控件,“不显示”就从父控件中移除。

注:这里用“显示”和“不显示”表述不太确切,因为ViewPager默认会多加载前一页(-1页)和后一页(1页)作为缓存页,缓存页没有显示时也会加载到父控件且不会被移除,当缓存页移到-2页或2页时才会被移除。

public class AZPagerAdapter extends PagerAdapter {

    protected List<View> views;

    public AZPagerAdapter(List<View> viewList) {
        views = viewList;
    }
    @Override
    public int getCount() {
        return views.size();
    }

    @Override
    public boolean isViewFromObject(View view, Object o) {
        return view == o;
    }

    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        container.removeView(views.get(position));
    }

    @Override
    public Object instantiateItem(ViewGroup container, int position) {
        container.addView(views.get(position));
        return views.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

现在的效果:

这里写图片描述

# 2.用PageTransformer来改变ViewPager的切换动画

ViewPager有个方法叫做:

setPageTransformer(boolean reverseDrawingOrder, PageTransformer transformer) 用于设置ViewPager切换时的动画效果。 这里写图片描述

这里我们只要自定义一个PageTransformer来实现我们需要的动画偏移效果就好了!

public class ScrollOffsetTransformer implements PageTransformer {
    /** * position参数指明给定页面相对于屏幕中心的位置。它是一个动态属性,会随着页面的滚动而改变。 * 当一个页面(page)填充整个屏幕时,positoin值为0; * 当一个页面(page)刚刚离开屏幕右(左)侧时,position值为1(-1); * 当两个页面分别滚动到一半时,其中一个页面是-0.5,另一个页面是0.5。 * 基于屏幕上页面的位置,通过诸如setAlpha()、setTranslationX()或setScaleY()方法来设置页面的属性,创建自定义的滑动动画。 */
    @Override
    public void transformPage(View page, float position) {
        if (position > 0) {
            //右侧的缓存页往左偏移100
            page.setTranslationX(-100 * position);
        }
    }
}
1
2
3
4
5
6
7
8
9
10

然后在init()方法中最后加上

viewPager.setPageTransformer(true, new ScrollOffsetTransformer());
1

看下效果:

这里写图片描述

已经可以看到后面一页内容的会偏移到前面一页来(背景色都用了半透明可以看到有叠加部分)!

不过有个问题,就是翻页(1页到0位置)过程中,原本处于2页的view要等到1页完全到0位置后才会突然显示(加载)出来(不是逐渐增加偏移量出来的)。这个原因其实就是刚刚讲Adapter的时候说的,ViewPager默认缓存3页(前页【-1页】,当前页【0页】,后页【1页】),而2页要等到1页到0位置后才会开始加载,(1页到0位置后变为0页,原来的0页变为-1页,原来的-1页被销毁)。

# 3.通过setOffscreenPageLimit(int limit)来改变缓存页数

解决上面遗留的问题也非常简单,就是改变ViewPager的默认缓存页数,使得它多缓存一页(2页)。

ViewPager有个方法叫做:

setOffscreenPageLimit(int limit) 用于设置ViewPager两边(左边和右边)各缓存的页数,默认是1,即左边和右边各缓存1页。

在init()方法最后再加上一句:

//左右各多加载2页(默认1页)
    viewPager.setOffscreenPageLimit(2);
1
2

看下最后效果:

这里写图片描述 大功告成!现在就平滑多了!

# 4.彩蛋

把ScrollOffsetTransformer里面稍微改一下,去掉条件判断后

public class ScrollOffsetTransformer implements PageTransformer {
    @Override
    public void transformPage(View page, float position) {
       // if (position > 0) {
            page.setTranslationX(-100 * position);
       // }
    }
}
1
2
3
4
5
6
7
8

前后都偏移啦!可以开发脑洞想一下用在有趣的地方!

这里写图片描述


源码地址:[https://github.com/Xieyupeng520/TestViewPager](javascript:void())

编辑 (opens new window)
上次更新: 2021/06/02, 10:01:48
ViewPager基础
结合TabLayout使用

← ViewPager基础 结合TabLayout使用→

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