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

机顶盒项目有个需求,在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));
}

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

现在的效果:

【Android实战】用ViewPager偏移看到下一页部分内容_第1张图片

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

ViewPager有个方法叫做:

setPageTransformer(boolean reverseDrawingOrder, PageTransformer transformer) 用于设置ViewPager切换时的动画效果。

官方实现图例:

【Android实战】用ViewPager偏移看到下一页部分内容_第2张图片

这里我们只要自定义一个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);
        }
    }
}

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

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

看下效果:

【Android实战】用ViewPager偏移看到下一页部分内容_第3张图片

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

不过有个问题,就是翻页(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);

看下最后效果:

【Android实战】用ViewPager偏移看到下一页部分内容_第4张图片
大功告成!现在就平滑多了!

4.彩蛋

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

public class ScrollOffsetTransformer implements PageTransformer {
    @Override
    public void transformPage(View page, float position) {
       // if (position > 0) {
            page.setTranslationX(-100 * position);
       // }
    }
}

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


【Android实战】用ViewPager偏移看到下一页部分内容_第5张图片

源码地址:https://github.com/Xieyupeng520/TestViewPager
(喜欢的话点下右上方的star,谢谢^_^~)

如果你有任何问题,欢迎留言告诉我!~

你可能感兴趣的:(android,viewpager,机顶盒,偏移,切换动画)