昨日朋友给我看了下这样的效果,我觉得很有意思,今日闲下来便写了这篇文章,并且传到了github,本文的末尾也附上了链接。网上有很多关于使用Gallery来打造3D画廊的博客,但是做出来的效果我不是很满意,有些许卡顿,索性就选择了viewpager来做,进入正题:下图为效果图。

一、要实现如下图的功能,需要以下3个方法:

(1)public Object instantiateItem(ViewGroup container, int position)

这个方法是负责向ViewGroup也就是ViewPager中添加新的页面,并返回一个继承自Object的key,这个key将会在第三个方法destroyItem和第四个方法isViewFromObject中作为参数调用。

  代码可以写成这样:

           @Overridepublic Object instantiateItem(ViewGroup container, int position) {ImageView imageView=imageViewList.get(position);container.addView(imageView,position);return imageView;}

(2)public void destroyItem(ViewGroup container, int position, Object object)

  该方法负责从ViewGroup中移除对应position中的page

  代码:

@Overridepublic void destroyItem(ViewGroup container, int position, Object object) {container.removeView(imageViewList.get(position));}

(3)public boolean isViewFromObject(View view, Object object)

  确定instantiateItem返回的特定key 对象是否与page View有关联。由于instantiateItem中可以以自身page为key返回,所以在这里就可以这样写:

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

ViewPager作为布局管理器,非常强大,也可以用来展示Fragment,当然adapter需要使用FragmentPagerAdapter或者FragmentStatePagerAdapter。

二、设置PageTransformer

PageTransformer是ViewPager的一个公共成员接口,用于设置当一个页面滑入和滑出的过度特效,当然,由于是通过属性动画来设置的,所以设置的pagetransformer在Android3.0以下会被忽略。

关于实现该接口,只需要实现一个方法即可:

 

 public void transformPage(View page, float position);

对于参数position,需要好好说明一下:

position的取值有如下说明:

position是指的是页面相对于中间页面的位置参数,根据位置不同,0的时候在中间最前面,1的时候页面完全在右边,-1的时候页面完全在左边。如下图所示:

关于该接口的更多知识可以看鸿洋大大的这篇博客:http://blog.csdn.net/lmj623565791/article/details/40411921/

那么要实现上面的效果要怎么做呢?

代码如下:

MyTransformation.java

*** @author:程龙 date; On 2018/9/19*/
public class MyTransformation implements ViewPager.PageTransformer {private static final float MIN_SCALE = 0.85f;private static final float MIN_ALPHA = 0.5f;private static final float MAX_ROTATE = 30;private Camera camera = new Camera();@Overridepublic void transformPage(View page, float position) {float centerX = page.getWidth() / 2;float centerY = page.getHeight() / 2;float scaleFactor = Math.max(MIN_SCALE, 1 - Math.abs(position));float rotate = 20 * Math.abs(position);if (position < -1) {} else if (position < 0) {page.setScaleX(scaleFactor);page.setScaleY(scaleFactor);page.setRotationY(rotate);} else if (position >= 0 && position < 1) {page.setScaleX(scaleFactor);page.setScaleY(scaleFactor);page.setRotationY(-rotate);} else if (position >= 1) {page.setScaleX(scaleFactor);page.setScaleY(scaleFactor);page.setRotationY(-rotate);}}
}

然后,

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

同时呢我在运行的时候发现了两个问题,

(1)为解决不在ViewPager中间页面被剪掉的问题:

  需要在ViewPager和其父容器中设置clipChildren为false

<?xml version="1.0" encoding="utf-8"?>
<LinearLayoutxmlns: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:orientation="vertical"android:id="@+id/activity_main"android:layout_width="match_parent"android:layout_height="match_parent"android:clipChildren="false"android:layerType="software"android:background="@android:color/black"tools:context="com.example.evanzeng.viewpagertest.MainActivity"><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="Hello World!"/><android.support.v4.view.ViewPagerandroid:id="@+id/viewPager"android:layout_width="wrap_content"android:layout_height="400dp"android:layout_gravity="center"android:clipChildren="false"></android.support.v4.view.ViewPager>
</LinearLayout>

 (2)为解决触摸滑动ViewPager左右两边的页面无反应的问题:

  需要为ViewPager的父容器设置OnTouchListener,将触摸事件传递给ViewPager

findViewById(R.id.activity_main).setOnTouchListener(new View.OnTouchListener() {@Overridepublic boolean onTouch(View view, MotionEvent motionEvent) {return viewPager.dispatchTouchEvent(motionEvent);}});

三、获取图片倒影

代码如下:

public class ImageUtil {public static Bitmap getReverseBitmapById(int resId, Context context){Bitmap sourceBitmap= BitmapFactory.decodeResource(context.getResources(),resId);Matrix matrix=new Matrix();matrix.setScale(1,-1);Bitmap inverseBitmap=Bitmap.createBitmap(sourceBitmap,0,sourceBitmap.getHeight()/2,sourceBitmap.getWidth(),sourceBitmap.getHeight()/3,matrix,false);Bitmap groupbBitmap=Bitmap.createBitmap(sourceBitmap.getWidth(),sourceBitmap.getHeight()+sourceBitmap.getHeight()/3+60,sourceBitmap.getConfig());Canvas gCanvas=new Canvas(groupbBitmap);gCanvas.drawBitmap(sourceBitmap,0,0,null);gCanvas.drawBitmap(inverseBitmap,0,sourceBitmap.getHeight()+50,null);Paint paint=new Paint();Shader.TileMode tileMode= Shader.TileMode.CLAMP;LinearGradient shader=new LinearGradient(0,sourceBitmap.getHeight()+50,0,groupbBitmap.getHeight(), Color.BLACK,Color.TRANSPARENT,tileMode);paint.setShader(shader);paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));gCanvas.drawRect(0,sourceBitmap.getHeight()+50,sourceBitmap.getWidth(),groupbBitmap.getHeight(),paint);return groupbBitmap;}
}

以上代码已上传自Github,地址如下:https://github.com/Cdlpj/CdlGalleryViewpager

demo下载:点击下载

如果您觉得不错的话对你有帮助就点个赞,有意见可在下方探讨,谢谢!

Andrid自定义view:打造3D画廊相关推荐

  1. android viewPage 打造3d画廊

    之前学习时学习了ViewPager打造3d画廊,今天找出来把他贴上去,给需要的小伙伴用!废话不多说直接贴! 一.Activity /*** 3da 画廊*/ public class Main3Act ...

  2. [原创]自定义ViewPager实现3D画廊效果

    经常在群里看到有些开发者在提问:怎么实现3D画廊效果,没思路. 有人出谋划策,你重写onTouch,在里面去判断:或者你去重写滑动监听事件,滑动的时候去动态设置左右两边的图片的大小和缩放效果.可能你们 ...

  3. Android 自定义View之3D骰子旋转

    你可以指定立方体中每一面骰子的点数,颜色和背景,同时也可以指定执行的动画时间和动画插值器 更多有趣的view 使用 在根目录的build.gradle添加这一句代码: allprojects {rep ...

  4. Android 系统(264)---android进阶——自定义View

    android进阶--自定义View 软件架构 01.自定义View简介 - onMeasure,onDraw,自定义属性  https://www.jianshu.com/p/48944aad200 ...

  5. 一篇文章带你走近Android自定义view

    系列文章目录 一篇文章带你走近Android自定义view 文章目录 系列文章目录 前言 一.为什么要自定义view 二.先看看一个超级简单的自定义view(三个构造函数) 三.了解手机的坐标系 四. ...

  6. android fragment中引入自定义view_厉害了,用Android自定义View实现八大行星绕太阳3D旋转效果...

    作者:史蒂芬诺夫斯基 链接:https://www.jianshu.com/p/2954f2ef8ea5 好久没写View了,最近恰巧遇到一个八大行星绕太阳旋转的假3D效果,写完之后感觉效果还不错.能 ...

  7. 【Android 仿微信通讯录 导航分组列表-下】自定义View为RecyclerView打造右侧索引导航栏IndexBar

    本篇文章已授权微信公众号 guolin_blog (郭霖)独家发布 转载请标明出处: http://blog.csdn.net/zxt0601/article/details/52420706 本文出 ...

  8. 60.自定义View练习(五)高仿小米时钟 - 使用Camera和Matrix实现3D效果

    *本篇文章已授权微信公众号 guolin_blog (郭霖)独家发布 本文出自:猴菇先生的博客 http://blog.csdn.net/qq_31715429/article/details/546 ...

  9. 什么?!!你从来没用SVG打造过不规则的自定义View?

    目录 SVG概念 SVG特性 SVG在安卓中能做什么 标准SVG预览 SVG语法介绍 SVG图片的生成 SVG图下载地址 巴铁!奔跑的小恐龙?(示例开始) 自定义View展示SVG SVG概念 SVG ...

最新文章

  1. mysql登陆 host_mysql远程可以登陆本地登陆不了(user表中host字段的通配符%)
  2. ThreadLocal怎么实现线程隔离的?可见性问题?为什么要重新定义一个threadLocalHashCode?为什么有内存泄露?弱引用又是什么?
  3. EL调用java方法
  4. 学生物的女朋友都能看懂的哈希表总结!
  5. list中随机获取n条、随机生成4位6位数工具类,1-n范围随机数,Math.random()生成随机数
  6. Atitit 互联网 技术公司的组织架构 事业部 分公司
  7. 身份证编码与校验码计算规则
  8. 正弦交流电的最大值、有效值、和瞬间值概念解析和计算
  9. 使用WSS的Lists.UpdateListItems()方法之被截断的CAML
  10. 工商管理专业的毕业论文怎么选题?
  11. 拍牌(沪牌)软件,开源全部代码。有精力可以自己研究然后自用拍牌
  12. Python实现日周月排行榜
  13. 如何估算一个项目的成本:CAPEX与OPEX的区别
  14. 使用密码字典 和 Python自带的pywifi模块穷举WIFI密码
  15. 将Windows XP 中文版变为英文版
  16. 以友盟+U-Push为例,深度解读消息推送的筛选架构解决方案应用与实践
  17. mysql之数据库引擎
  18. TomCat 启动报:validateJarFile jar not loaded. See Servlet Spec 2.3, section 9.7.2.
  19. 关于产品的一些思考——新浪之爱问资料和爱问知识人
  20. Echarts气泡图(相邻效果,气泡之间不叠加)

热门文章

  1. java 相对路径转绝对路径_Java相对路径/绝对路径总结(转)
  2. 疯狂的蚂蚁----ant
  3. 信息安全数学基础 Chapter 1——整除
  4. 24.重学webpack——loader的原理及常用loader的实现(高频面试题)
  5. 灵魂拷问:java的String到底可不可变?
  6. JAVA接口案例(猫和狗、运动员和教练)
  7. freemarker创建模板文件常用标签
  8. 如何将ZAP加入到FoxyProxy代理工具
  9. 各路大咖云集探讨eBPF技术在可观测性领域的落地现状和未来可能
  10. 用cmd控制台编译java文件和运行class文件