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这个应用的首页:

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

代码:

[java] view plaincopy print?
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <RelativeLayout
  3. xmlns:android="http://schemas.android.com/apk/res/android"
  4. xmlns:tools="http://schemas.android.com/tools"
  5. android:layout_width="match_parent"
  6. android:layout_height="match_parent"
  7. android:clipChildren="false"
  8. tools:context="org.lenve.clipchildren.MainActivity">
  9. <LinearLayout
  10. android:layout_width="match_parent"
  11. android:layout_height="48dp"
  12. android:layout_alignParentBottom="true"
  13. android:background="#03b9fc"
  14. android:orientation="horizontal">
  15. <ImageView
  16. android:layout_width="0dp"
  17. android:layout_height="match_parent"
  18. android:layout_weight="1"
  19. android:src="@mipmap/ic_launcher"/>
  20. <ImageView
  21. android:layout_width="0dp"
  22. android:layout_height="match_parent"
  23. android:layout_weight="1"
  24. android:src="@mipmap/ic_launcher"/>
  25. <ImageView
  26. android:layout_width="0dp"
  27. android:layout_height="72dp"
  28. android:layout_gravity="bottom"
  29. android:layout_weight="1"
  30. android:src="@mipmap/ic_launcher"/>
  31. <ImageView
  32. android:layout_width="0dp"
  33. android:layout_height="match_parent"
  34. android:layout_weight="1"
  35. android:src="@mipmap/ic_launcher"/>
  36. <ImageView
  37. android:layout_width="0dp"
  38. android:layout_height="match_parent"
  39. android:layout_weight="1"
  40. android:src="@mipmap/ic_launcher"/>
  41. </LinearLayout>
  42. </RelativeLayout>

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

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

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

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

[java] view plaincopy print?
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <RelativeLayout
  3. xmlns:android="http://schemas.android.com/apk/res/android"
  4. xmlns:tools="http://schemas.android.com/tools"
  5. android:layout_width="match_parent"
  6. android:layout_height="match_parent"
  7. android:clipChildren="false"
  8. tools:context="org.lenve.myviewpagercards.MainActivity">
  9. <android.support.v4.view.ViewPager
  10. android:id="@+id/viewpager"
  11. android:layout_width="match_parent"
  12. android:layout_height="200dp"
  13. android:layout_marginLeft="60dp"
  14. android:layout_marginRight="60dp"
  15. android:clipChildren="false"></android.support.v4.view.ViewPager>
  16. </RelativeLayout>

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

[java] view plaincopy print?
  1. public class MyVpAdater extends PagerAdapter {
  2. private List<Integer> list;
  3. private Context context;
  4. public MyVpAdater(Context context, List<Integer> list) {
  5. this.context = context;
  6. this.list = list;
  7. }
  8. @Override
  9. public int getCount() {
  10. return list.size();
  11. }
  12. @Override
  13. public boolean isViewFromObject(View view, Object object) {
  14. return view == object;
  15. }
  16. @Override
  17. public Object instantiateItem(ViewGroup container, int position) {
  18. ImageView iv = new ImageView(context);
  19. iv.setImageResource(list.get(position));
  20. container.addView(iv);
  21. return iv;
  22. }
  23. @Override
  24. public void destroyItem(ViewGroup container, int position, Object object) {
  25. container.removeView((View) object);
  26. }
  27. }

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

[java] view plaincopy print?
  1. ViewPager viewPager = (ViewPager) findViewById(R.id.viewpager);
  2. viewPager.setPageMargin(80);
  3. viewPager.setOffscreenPageLimit(3);
  4. List<Integer> list = new ArrayList<>();
  5. list.add(R.drawable.p001);
  6. list.add(R.drawable.p002);
  7. list.add(R.drawable.p003);
  8. list.add(R.drawable.p004);
  9. list.add(R.drawable.p005);
  10. MyVpAdater adater = new MyVpAdater(this, list);
  11. viewPager.setAdapter(adater);

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

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都有一点透明度。那我们可以使用如下方式来定义:

[java] view plaincopy print?
  1. public class AlphaTransformer implements ViewPager.PageTransformer {
  2. private float MINALPHA = 0.5f;
  3. /**
  4. * position取值特点:
  5. * 假设页面从0~1,则:
  6. * 第一个页面position变化为[0,-1]
  7. * 第二个页面position变化为[1,0]
  8. *
  9. * @param page
  10. * @param position
  11. */
  12. @Override
  13. public void transformPage(View page, float position) {
  14. if (position < -1 || position > 1) {
  15. page.setAlpha(MINALPHA);
  16. } else {
  17. //不透明->半透明
  18. if (position < 0) {//[0,-1]
  19. page.setAlpha(MINALPHA + (1 + position) * (1 - MINALPHA));
  20. } else {//[1,0]
  21. //半透明->不透明
  22. page.setAlpha(MINALPHA + (1 - position) * (1 - MINALPHA));
  23. }
  24. }
  25. }
  26. }

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

[java] view plaincopy print?
  1. viewPager.setPageTransformer(false, new AlphaTransformer());

我们再来看看运行效果:

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

4.进一步了解PagerTransformer

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

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

[java] view plaincopy print?
  1. public class ScaleTransformer implements ViewPager.PageTransformer {
  2. private static final float MIN_SCALE = 0.70f;
  3. private static final float MIN_ALPHA = 0.5f;
  4. @Override
  5. public void transformPage(View page, float position) {
  6. if (position < -1 || position > 1) {
  7. page.setAlpha(MIN_ALPHA);
  8. page.setScaleX(MIN_SCALE);
  9. page.setScaleY(MIN_SCALE);
  10. } else if (position <= 1) { // [-1,1]
  11. float scaleFactor = Math.max(MIN_SCALE, 1 - Math.abs(position));
  12. if (position < 0) {
  13. float scaleX = 1 + 0.3f * position;
  14. Log.d("google_lenve_fb", "transformPage: scaleX:" + scaleX);
  15. page.setScaleX(scaleX);
  16. page.setScaleY(scaleX);
  17. } else {
  18. float scaleX = 1 - 0.3f * position;
  19. page.setScaleX(scaleX);
  20. page.setScaleY(scaleX);
  21. }
  22. page.setAlpha(MIN_ALPHA + (scaleFactor - MIN_SCALE) / (1 - MIN_SCALE) * (1 - MIN_ALPHA));
  23. }
  24. }
  25. }

然后给ViewPager设置相应的PagerTransformer:

[java] view plaincopy print?
  1. viewPager.setPageTransformer(false, new ScaleTransformer());

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

5.ViewPager结合CardView

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

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

[java] view plaincopy print?
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <RelativeLayout
  3. xmlns:android="http://schemas.android.com/apk/res/android"
  4. xmlns:tools="http://schemas.android.com/tools"
  5. android:layout_width="match_parent"
  6. android:layout_height="match_parent"
  7. tools:context="org.lenve.myviewpagercards2.MainActivity">
  8. <android.support.v4.view.ViewPager
  9. android:id="@+id/viewpager"
  10. android:layout_width="match_parent"
  11. android:layout_height="200dp"
  12. android:clipToPadding="false"
  13. android:paddingBottom="24dp"
  14. android:paddingLeft="48dp"
  15. android:paddingRight="48dp"
  16. android:paddingTop="24dp"></android.support.v4.view.ViewPager>
  17. </RelativeLayout>

ViewPager的Adapter如下:

[java] view plaincopy print?
  1. public class MyAdapter extends PagerAdapter {
  2. private List<Integer> list;
  3. private Context context;
  4. public MyAdapter(Context context, List<Integer> list) {
  5. this.context = context;
  6. this.list = list;
  7. }
  8. @Override
  9. public int getCount() {
  10. return list.size();
  11. }
  12. @Override
  13. public boolean isViewFromObject(View view, Object object) {
  14. return view == object;
  15. }
  16. @Override
  17. public Object instantiateItem(ViewGroup container, int position) {
  18. ImageView iv = new ImageView(context);
  19. iv.setImageResource(list.get(position));
  20. container.addView(iv);
  21. return iv;
  22. }
  23. @Override
  24. public void destroyItem(ViewGroup container, int position, Object object) {
  25. container.removeView((View) object);
  26. }
  27. }

Activity中的代码:

[java] view plaincopy print?
  1. ViewPager viewPager = (ViewPager) findViewById(R.id.viewpager);
  2. List<Integer> list = new ArrayList<>();
  3. list.add(R.drawable.p001);
  4. list.add(R.drawable.p002);
  5. list.add(R.drawable.p003);
  6. list.add(R.drawable.p004);
  7. list.add(R.drawable.p005);
  8. MyAdapter adapter = new MyAdapter(this, list);
  9. viewPager.setAdapter(adapter);
  10. viewPager.setPageMargin(20);

显示效果如下:

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

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

[java] view plaincopy print?
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <RelativeLayout
  3. xmlns:android="http://schemas.android.com/apk/res/android"
  4. xmlns:tools="http://schemas.android.com/tools"
  5. android:layout_width="match_parent"
  6. android:layout_height="match_parent"
  7. tools:context="org.lenve.myviewpagercards2.MainActivity">
  8. <android.support.v4.view.ViewPager
  9. android:id="@+id/viewpager"
  10. android:layout_width="match_parent"
  11. android:layout_height="300dp"
  12. android:clipToPadding="false"
  13. android:paddingBottom="24dp"
  14. android:paddingLeft="80dp"
  15. android:paddingRight="80dp"
  16. android:paddingTop="24dp"></android.support.v4.view.ViewPager>
  17. </RelativeLayout>

ViewPager中每一个item的布局:

[java] view plaincopy print?
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <android.support.v7.widget.CardView android:id="@+id/cardview"
  3. xmlns:android="http://schemas.android.com/apk/res/android"
  4. xmlns:app="http://schemas.android.com/apk/res-auto"
  5. android:layout_width="match_parent"
  6. android:layout_height="wrap_content"
  7. android:orientation="vertical"
  8. app:cardCornerRadius="10dp">
  9. <RelativeLayout
  10. android:layout_width="match_parent"
  11. android:layout_height="300dp">
  12. <TextView
  13. android:id="@+id/tv"
  14. android:layout_width="match_parent"
  15. android:layout_height="wrap_content"
  16. android:layout_centerInParent="true"
  17. android:gravity="center"
  18. android:text="我是一个TextView"/>
  19. <Button
  20. android:layout_width="96dp"
  21. android:layout_height="36dp"
  22. android:textColor="#ffffff"
  23. android:layout_below="@id/tv"
  24. android:layout_centerHorizontal="true"
  25. android:layout_marginTop="12dp"
  26. android:background="@color/colorAccent"
  27. android:text="我是一个按钮"/>
  28. </RelativeLayout>
  29. </android.support.v7.widget.CardView>

Adapter:

[java] view plaincopy print?
  1. public class MyAdapter extends PagerAdapter {
  2. private List<Integer> list;
  3. private Context context;
  4. private LayoutInflater inflater;
  5. public MyAdapter(Context context, List<Integer> list) {
  6. this.context = context;
  7. this.list = list;
  8. inflater = LayoutInflater.from(context);
  9. }
  10. @Override
  11. public int getCount() {
  12. return list.size();
  13. }
  14. @Override
  15. public boolean isViewFromObject(View view, Object object) {
  16. return view == object;
  17. }
  18. @Override
  19. public Object instantiateItem(ViewGroup container, int position) {
  20. View view = inflater.inflate(R.layout.vp_item, container, false);
  21. container.addView(view);
  22. return view;
  23. }
  24. @Override
  25. public void destroyItem(ViewGroup container, int position, Object object) {
  26. container.removeView((View) object);
  27. }
  28. }

Activity中的代码:

[java] view plaincopy print?
  1. ViewPager viewPager = (ViewPager) findViewById(R.id.viewpager);
  2. List<Integer> list = new ArrayList<>();
  3. list.add(R.drawable.p001);
  4. list.add(R.drawable.p002);
  5. list.add(R.drawable.p003);
  6. list.add(R.drawable.p004);
  7. list.add(R.drawable.p005);
  8. MyAdapter adapter = new MyAdapter(this, list);
  9. viewPager.setAdapter(adapter);
  10. viewPager.setPageMargin((int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
  11. 48, getResources().getDisplayMetrics()));
  12. viewPager.setPageTransformer(false, new ScaleTransformer(this));

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

[java] view plaincopy print?
  1. public class ScaleTransformer implements ViewPager.PageTransformer {
  2. private Context context;
  3. private float elevation;
  4. public ScaleTransformer(Context context) {
  5. this.context = context;
  6. elevation = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
  7. 20, context.getResources().getDisplayMetrics());
  8. }
  9. @Override
  10. public void transformPage(View page, float position) {
  11. if (position < -1 || position > 1) {
  12. } else {
  13. if (position < 0) {
  14. ((CardView) page).setCardElevation((1 + position) * elevation);
  15. } else {
  16. ((CardView) page).setCardElevation((1 - position) * elevation);
  17. }
  18. }
  19. }
  20. }

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

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

参考资料:

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

以上。

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

  1. 卡片式UI设计详细指南,先收好这8条!

    今天为大家分享的是「卡片设计」. 卡片是产品中常见的设计组件之一.通过卡片,可以将不同的内容分层次组合在一起.卡片式设计自带简约和易用的属性,能让页面看起来更有秩序感. 卡片作为常用的UI组件,通常由 ...

  2. 报表工具轻松搞定卡片式报表

    在我们日常生活或工作中,经常会看到这样一个个小卡片,上面记载着某件商品或者某个人的基本信息.如同名片一般,看起来简单明了.而在数据库中,这些信息实际上是密密麻麻的一条条记录,直接查看非常容易看错,如下 ...

  3. 如何快速制作名片/卡片式报表

    在我们日常生活或工作中,经常会看到这样一个个小卡片,上面记载着某件商品或者某个人的基本信息.如同名片一般,看起来简单明了.而在数据库中,这些信息实际上是密密麻麻的一条条记录,直接查看非常容易看错,如下 ...

  4. 谈什么是卡片式设计?

    卡片式设计 卡片,你或许不熟悉这个术语,但是你绝对不会对卡片的概念感觉陌生.现在,卡片在网页设计中是普遍存在的,并且还将越来越流行.事实上,Google,Twitter和Facebook这三大受推崇的 ...

  5. 可爱的小幽灵跟随鼠标动画卡片式404页面源码

    简介: 一个卡片式的404页面,非常可爱的小幽灵一上一下飘动,眼睛会随着鼠标的移动而转动. 虽是幽灵,但没有一点恐怖的感觉,更多的只有可爱. 很多萝莉控一定会喜欢的. 这段时间一直坚持每天更新,喜欢的 ...

  6. 一个垃圾分类项目带你玩转飞桨(1)

    一个垃圾分类项目带你玩转飞桨(1) 基于PaddleClas实现垃圾分类,导出inference模型并利用PaddleHub Serving进行服务化部署. 更好的体验记得移步AIStudio哟~ 点 ...

  7. 【转】带你玩转Visual Studio——02.带你新建一个工程

    接着上一篇文章带你玩转Visual Studio--开篇介绍继续讲这个主题,现在我们从创建一个新的工程开始. 一步一步创建项目 依次选择菜单:File\New\Project,打开New Projec ...

  8. 一个垃圾分类项目带你玩转飞桨(2)

    一个垃圾分类项目带你玩转飞桨(2) 接上文<一个垃圾分类项目带你玩转飞桨(1)>:基于PaddleClas实现垃圾分类,导出inference模型利用PaddleHub Serving 进 ...

  9. 疯狂的大柚柚带你玩转MSP-ESP430G2(基础篇) -----(五)点亮一个LED(CCS)

    疯狂的大柚柚带你玩转MSP-ESP430G2(基础篇) (五)点亮一个LED 由电路图可知板载LED1 与P1.0 相连 #include <msp430.h> void main (vo ...

  10. 疯狂的大柚柚带你玩转MSP-ESP430G2(基础篇)——(三)ESP430G2实例:点亮一个LED(Energia)

    疯狂的大柚柚带你玩转MSP-ESP430G2(基础篇) (三)ESP430G2实例:点亮一个LED 发光二极管为半导体二极管的一种是将电能转化为光能,通常简称LED.与普通二极管相同由PN结组成,并具 ...

最新文章

  1. python的源代码文件的扩展名是-python源文件后缀是什么
  2. 涉足计算机视觉领域要知道的
  3. java ee会员功能项目_基于jsp的会员系统-JavaEE实现会员系统 - java项目源码
  4. python3编译器怎么下载_Python编译器及Sublime Text3安装及开发环境配置
  5. noi99钉子和小球 解题报告
  6. Java VisualVM 插件地址,安装Visual VM插件,修改下载插件地址使插件可以直接在JVisualVM中进行下载
  7. IEDA中彻底删除项目
  8. 如何创建新的SAP CRM middleware subscription
  9. Drawwhile计算机软件,计算机程序设计、小女纸又怒编一程序、求鉴定、
  10. Java 中接口 interface 实例介绍
  11. Tomcat9 安装与配置
  12. Havel-Hakimi定理 POJ1659
  13. sdk 今日头条_Unity接入今日头条广告(激励广告)
  14. matlab 中.*和* 区别
  15. Chrome谷歌浏览器连接路由器不上
  16. Python实现四子棋(四连环)游戏
  17. python接私活王者_[宜配屋]听图阁
  18. Visual Studio中更改项目名称
  19. PC纯净版win7系统安装
  20. Nexus 5设备调试

热门文章

  1. Quoit Design
  2. 对“xxx”类型的已垃圾回收委托进行了回调。这可能会导致应用程序崩溃、损坏和数据丢失。向非托管代码传递委托时,托管应用程序必须让这些委托保持活动状态,直到确信不会再次调用它们。...
  3. java操作无符号数
  4. gdi和gdi+并用
  5. Opencv2.X以上Mat类型与IplImage*的转换
  6. 升级Xcode之后VVDocumenter-Xcode不能用的解决办法
  7. EasyRecovery如何恢复虚拟建模软件的数据文件
  8. GRU门控制循环单元【转载】
  9. 两个整形变量的值进行交换
  10. win10下的selenium + python环境搭建