一个卡片式的ViewPager,带你玩转ViewPager的PageTransformer属性!

一个卡片式的ViewPager,带你玩转ViewPager的PageTransformer属性!我知道你会用ViewPager,可你在ViewPager中用过Android5.0新控件CardView么?你用过PageTransformer属性吗?搞懂这几个,让你的ViewPager大放异彩!

大家好,又见面了,我是你们的朋友全栈君。

ViewPager的基本用法不必多说,这都很简单,我们可以在ViewPager中加载一个ImageView,也可以加载一个Fragment,这都是目前非常常见的用法。那么我今天说的是ViewPager中的PageTransformer属性,用好这个属性可以让我们的应用更加出彩,OK,那我们就开始吧!

本文将从如下几方面来介绍:

1.clipChildren属性
2.一个页面显示多个ViewPager的Item
3.初识PagerTransformer
4.进一步了解PagerTransformer
5.ViewPager结合CardView

1.clipChildren属性

clipChildren属性表示是否限制子控件在该容器所在的范围内,clipChildren属性配合layout_gravity属性,可以用来设置多余部分的显示位置,我这里举一个简单的例子,比如喜马拉雅FM这个应用的首页:

一个卡片式的ViewPager,带你玩转ViewPager的PageTransformer属性!

大家注意看这个应用底部导航栏中中间一个是要比另外四个高的,这种效果很多人就会想到使用一个RelativeLayout布局来实现,其实不用那么麻烦,这种效果一个clipChildren属性就能实现,示例Demo如下:

代码:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:clipChildren="false"
    tools:context="org.lenve.clipchildren.MainActivity">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="48dp"
        android:layout_alignParentBottom="true"
        android:background="#03b9fc"
        android:orientation="horizontal">

        <ImageView
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:src="@mipmap/ic_launcher"/>

        <ImageView
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:src="@mipmap/ic_launcher"/>

        <ImageView
            android:layout_width="0dp"
            android:layout_height="72dp"
            android:layout_gravity="bottom"
            android:layout_weight="1"
            android:src="@mipmap/ic_launcher"/>

        <ImageView
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:src="@mipmap/ic_launcher"/>

        <ImageView
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:src="@mipmap/ic_launcher"/>
    </LinearLayout>
</RelativeLayout>

大家看只需要在根节点添加clipChildren属性,然后在第三个ImageView上添加layout_gravity属性即可,layout_gravity属性值为bottom表示控件大小超出后控件底部对齐。效果如下:

一个卡片式的ViewPager,带你玩转ViewPager的PageTransformer属性!

OK,上面是对clipChildren属性一个简单介绍,算是一个铺垫,接下来我们来看看ViewPager。

2.一个页面显示多个ViewPager的Item

我们要来解决的第一个问题是如何在一个页面上显示ViewPager的多个item,一共有两种解决方案,第一种就是我们上文所说的clipChildren属性,第二种是clipToPadding属性,我们先来看看使用第一种属性设置的ViewPager:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:clipChildren="false"
    tools:context="org.lenve.myviewpagercards.MainActivity">

    <android.support.v4.view.ViewPager
        android:id="@+id/viewpager"
        android:layout_width="match_parent"
        android:layout_height="200dp"
        android:layout_marginLeft="60dp"
        android:layout_marginRight="60dp"
        android:clipChildren="false"></android.support.v4.view.ViewPager>
</RelativeLayout>

只需要在父容器和ViewPager中都添加上clipChildren属性,然后给ViewPager设置左右两个margin,使其不致于把整个屏幕占满,就是这么简单,我们再来看看ViewPager的Adapter:

public class MyVpAdater extends PagerAdapter {
    private List<Integer> list;
    private Context context;

    public MyVpAdater(Context context, List<Integer> list) {
        this.context = context;
        this.list = list;
    }

    @Override
    public int getCount() {
        return list.size();
    }

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

    @Override
    public Object instantiateItem(ViewGroup container, int position) {
        ImageView iv = new ImageView(context);
        iv.setImageResource(list.get(position));
        container.addView(iv);
        return iv;
    }

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

最后再来看看Activity中的代码:

ViewPager viewPager = (ViewPager) findViewById(R.id.viewpager);
        viewPager.setPageMargin(80);
        viewPager.setOffscreenPageLimit(3);
        List<Integer> list = new ArrayList<>();
        list.add(R.drawable.p001);
        list.add(R.drawable.p002);
        list.add(R.drawable.p003);
        list.add(R.drawable.p004);
        list.add(R.drawable.p005);
        MyVpAdater adater = new MyVpAdater(this, list);
        viewPager.setAdapter(adater);

比我们一般使用ViewPager多了两行代码,一个是setOffscreenPageLimit,这个是设置预加载的页数,我们知道默认情况下这个参数为1,也就是左右各预加载一页,但是我们这里要让左右各预加载两页,原因一会再说,另外一个PageMargin就好说了,就是设置ViewPager中两页之间的距离。OK,那我们来看看显示效果:

一个卡片式的ViewPager,带你玩转ViewPager的PageTransformer属性!

OK,就是这么简单,这样,我们现在已经可以在一个页面上来显示多个ViewPager中的item,接下来我们先来看看PageTransformer的简单使用。

3.初识PagerTransformer

我们知道可以给ViewPager设置一个setPagerTransformer属性,设置时候需要我们自己来实现PagerTransformer接口,实现这个接口的时候要实现该接口中的方法,transformPage,该方法接收两个参数,其中一个是position,如果你直接打印position出来可能会看得你云里雾里,实际上position表示的是第一个参数View的position,把这两个参数一起打印出来就可以找到规律了:

比如从第1页滑动到第2页:

第一页position的变化为  [0,-1]

第二页position的变化为  [1,0]

知道了这个我们就可以写一个简单的切换动画了,我希望页面上正中间的item是正常的,两边的item都有一点透明度。那我们可以使用如下方式来定义:

public class AlphaTransformer implements ViewPager.PageTransformer {
    private float MINALPHA = 0.5f;

    /**
     * position取值特点:
     * 假设页面从0~1,则:
     * 第一个页面position变化为[0,-1]
     * 第二个页面position变化为[1,0]
     *
     * @param page
     * @param position
     */
    @Override
    public void transformPage(View page, float position) {
        if (position < -1 || position > 1) {
            page.setAlpha(MINALPHA);
        } else {
            //不透明->半透明
            if (position < 0) {//[0,-1]
                page.setAlpha(MINALPHA + (1 + position) * (1 - MINALPHA));
            } else {//[1,0]
                //半透明->不透明
                page.setAlpha(MINALPHA + (1 - position) * (1 - MINALPHA));
            }
        }
    }
}

定义好了之后再设置给ViewPager即可:

viewPager.setPageTransformer(false, new AlphaTransformer());

我们再来看看运行效果:

一个卡片式的ViewPager,带你玩转ViewPager的PageTransformer属性!

OK,透明度的效果已经有了。很简单吧!

4.进一步了解PagerTransformer

上面是一个简答的效果,遵循这个思路,我们可以做出更多的效果,比如下面这个效果:

一个卡片式的ViewPager,带你玩转ViewPager的PageTransformer属性!

这是一个非常常见的效果,实现思路和前文一致,就是让ImageView动态缩放。那我们来看看这里的PagerTransformer:

public class ScaleTransformer implements ViewPager.PageTransformer {
    private static final float MIN_SCALE = 0.70f;
    private static final float MIN_ALPHA = 0.5f;

    @Override
    public void transformPage(View page, float position) {
        if (position < -1 || position > 1) {
            page.setAlpha(MIN_ALPHA);
            page.setScaleX(MIN_SCALE);
            page.setScaleY(MIN_SCALE);
        } else if (position <= 1) { // [-1,1]
            float scaleFactor = Math.max(MIN_SCALE, 1 - Math.abs(position));
            if (position < 0) {
                float scaleX = 1 + 0.3f * position;
                Log.d("google_lenve_fb", "transformPage: scaleX:" + scaleX);
                page.setScaleX(scaleX);
                page.setScaleY(scaleX);
            } else {
                float scaleX = 1 - 0.3f * position;
                page.setScaleX(scaleX);
                page.setScaleY(scaleX);
            }
            page.setAlpha(MIN_ALPHA + (scaleFactor - MIN_SCALE) / (1 - MIN_SCALE) * (1 - MIN_ALPHA));
        }
    }
}

然后给ViewPager设置相应的PagerTransformer:

viewPager.setPageTransformer(false, new ScaleTransformer());

就是这么简单。其它复杂的旋转平移等都是按照这个思路来实现,这里不再赘述。

5.ViewPager结合CardView

如果你还不会使用CardView,可以参考我之前的文章Android5.0之CardView的使用,那今天我们来看看ViewPager结合CardView会产生怎样的效果呢?

那么在这之前,我想先介绍一个属性,那就是clipToPadding,这个属性是什么意思呢?它表示是否允许ViewGroup在ViewGroup的padding中进行绘制,默认情况下该属性的值为true,即不允许在ViewGroup的padding中进行绘制。那如果我设置了false呢?我们来看看:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="org.lenve.myviewpagercards2.MainActivity">

    <android.support.v4.view.ViewPager
        android:id="@+id/viewpager"
        android:layout_width="match_parent"
        android:layout_height="200dp"
        android:clipToPadding="false"
        android:paddingBottom="24dp"
        android:paddingLeft="48dp"
        android:paddingRight="48dp"
        android:paddingTop="24dp"></android.support.v4.view.ViewPager>
</RelativeLayout>

ViewPager的Adapter如下:

public class MyAdapter extends PagerAdapter {
    private List<Integer> list;
    private Context context;

    public MyAdapter(Context context, List<Integer> list) {
        this.context = context;
        this.list = list;
    }

    @Override
    public int getCount() {
        return list.size();
    }

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

    @Override
    public Object instantiateItem(ViewGroup container, int position) {
        ImageView iv = new ImageView(context);
        iv.setImageResource(list.get(position));
        container.addView(iv);
        return iv;
    }

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

Activity中的代码:

        ViewPager viewPager = (ViewPager) findViewById(R.id.viewpager);
        List<Integer> list = new ArrayList<>();
        list.add(R.drawable.p001);
        list.add(R.drawable.p002);
        list.add(R.drawable.p003);
        list.add(R.drawable.p004);
        list.add(R.drawable.p005);
        MyAdapter adapter = new MyAdapter(this, list);
        viewPager.setAdapter(adapter);
        viewPager.setPageMargin(20);

显示效果如下:

一个卡片式的ViewPager,带你玩转ViewPager的PageTransformer属性!

OK,那这个clipToPadding属性是我们在一个页面中显示多个ViewPager  item的第二种方式。这个CardView式的ViewPager我们就使用这种方式来实现。先来看看效果图:

一个卡片式的ViewPager,带你玩转ViewPager的PageTransformer属性!

整体思路和上文其实是一致的,我们来看看activity的布局:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="org.lenve.myviewpagercards2.MainActivity">

    <android.support.v4.view.ViewPager
        android:id="@+id/viewpager"
        android:layout_width="match_parent"
        android:layout_height="300dp"
        android:clipToPadding="false"
        android:paddingBottom="24dp"
        android:paddingLeft="80dp"
        android:paddingRight="80dp"
        android:paddingTop="24dp"></android.support.v4.view.ViewPager>
</RelativeLayout>

ViewPager中每一个item的布局:

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView android:id="@+id/cardview"
                                    xmlns:android="http://schemas.android.com/apk/res/android"
                                    xmlns:app="http://schemas.android.com/apk/res-auto"
                                    android:layout_width="match_parent"
                                    android:layout_height="wrap_content"
                                    android:orientation="vertical"
                                    app:cardCornerRadius="10dp">

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="300dp">

        <TextView
            android:id="@+id/tv"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true"
            android:gravity="center"
            android:text="我是一个TextView"/>

        <Button
            android:layout_width="96dp"
            android:layout_height="36dp"
            android:textColor="#ffffff"
            android:layout_below="@id/tv"
            android:layout_centerHorizontal="true"
            android:layout_marginTop="12dp"
            android:background="@color/colorAccent"
            android:text="我是一个按钮"/>
    </RelativeLayout>
</android.support.v7.widget.CardView>

Adapter:

public class MyAdapter extends PagerAdapter {
    private List<Integer> list;
    private Context context;
    private LayoutInflater inflater;

    public MyAdapter(Context context, List<Integer> list) {
        this.context = context;
        this.list = list;
        inflater = LayoutInflater.from(context);
    }
    @Override
    public int getCount() {
        return list.size();
    }

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

    @Override
    public Object instantiateItem(ViewGroup container, int position) {
        View view = inflater.inflate(R.layout.vp_item, container, false);
        container.addView(view);
        return view;
    }

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

Activity中的代码:

ViewPager viewPager = (ViewPager) findViewById(R.id.viewpager);
        List<Integer> list = new ArrayList<>();
        list.add(R.drawable.p001);
        list.add(R.drawable.p002);
        list.add(R.drawable.p003);
        list.add(R.drawable.p004);
        list.add(R.drawable.p005);
        MyAdapter adapter = new MyAdapter(this, list);
        viewPager.setAdapter(adapter);
        viewPager.setPageMargin((int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
                48, getResources().getDisplayMetrics()));
        viewPager.setPageTransformer(false, new ScaleTransformer(this));

最后再来看看我们定义的PageTransformer:

public class ScaleTransformer implements ViewPager.PageTransformer {
    private Context context;
    private float elevation;

    public ScaleTransformer(Context context) {
        this.context = context;
        elevation = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
                20, context.getResources().getDisplayMetrics());
    }

    @Override
    public void transformPage(View page, float position) {
        if (position < -1 || position > 1) {

        } else {
            if (position < 0) {
                ((CardView) page).setCardElevation((1 + position) * elevation);
            } else {
                ((CardView) page).setCardElevation((1 - position) * elevation);
            }
        }
    }
}

很简单,我只是对CardView的阴影做了处理 ,其他属性都没改,这样就有了我们刚才看到的效果。

Demo下载:http://download.csdn.net/detail/u012702547/9615195

参考资料:

http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2014/1030/1870.html

以上。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/163208.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • idea中关闭eslint[通俗易懂]

    idea中关闭eslint[通俗易懂]file-&gt;setting搜索eslint将Enable选项勾选掉

  • 阿帕基_jojo唯一一个没有荒木线的人

    阿帕基_jojo唯一一个没有荒木线的人阿帕基死前脑海里浮现的场景阿帕基:你在那里干什么啊?警察先生警察:抱歉打扰你吃饭了,我正在调查,我在采集指纹,昨晚,对面人行道上发生了一起抢劫案,被害者被人用酒瓶殴打,碎片散了一地。但人行道上的碎

  • 如何在vue项目中使用md5加密

    如何在vue项目中使用md5加密npm安装:npminstall–savejs-md51.在需要使用的项目文件中引入:importmd5from’js-md5′;使用:md5(‘holle’)//bcecb35d0a12baad472fbe0392bcc0432.或者在main.js文件中将md5转换成vue原型:importmd5from’js-md5…

  • java中timer怎么用_java out of memory

    java中timer怎么用_java out of memory当我通过按BACK按钮(调用onBackPressed())关闭应用程序时,CountDownTimer它不会停止,直到完成计数为止。我怎样才能把CountDownTimercancel();在我的onBackPressed()?因为,当我退出应用程序时(如下面的说明所示),我不再想要在屏幕上进行举杯了。在我的代码之上:booleannetwork_connected=false;我的是什…

  • hdu 2648 Shopping

    hdu 2648 Shopping

  • 使用PageOffice实现文档(word,excel,pdf)在线预览编辑[通俗易懂]

    使用PageOffice实现文档(word,excel,pdf)在线预览编辑[通俗易懂]最近发现一款不错的插件的PageOffice,地址是:http://www.zhuozhengsoft.com/Technical/他可以实现word,excel、pdf在线预览以及在线编辑。虽然商用的话需要收费,但是有免费的试用版,在实现自己毕业设计或是做样品的时候是一个不错的选择。他同时支持java\c#\php.一旦有了正真的项目花钱再买也可以。同时自己也可以熟悉如何使用。接着下面实现

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号