前言

自从清明放假之后,状态就一直一般般,(放假使我快乐,不要上学,我要放假!)导致更文也断了一段时间,鸽了好一段时间。痛定思痛,最近决定重新恢复更文。鉴于前段时间在学习扔物线大大 HenCoder 的自定义View系列文章,看到其中给出了一些可供仿写的酷界面,打算尝试仿写其中的 Flipboard 红板报的翻页效果(加强版)

动画效果如下:

分析

  • 核心:图片本身不旋转,旋转的是”翻折的 canvas “,在处理过后的canvas中绘制图片

    1. ”右侧”(指 最开始 “翻折的 canvas”)翻折一定角度,”左侧”(指 最后 “翻折的 canvas”)无变化,分别绘制;
    2. 将 “右侧” 旋转 270°,”左侧” 配合旋转,分别绘制;
    3. “右侧”无变化, “左侧” 翻折一定角度
  • 涉及知识点

    1. 属性动画 的使用,不了解的可以看我的另一篇分享Android 属性动画
    2. canvas 的使用,主要是 几何变换
    3. camera 的 旋转平移
    4. 关关关键 要区别二者的 坐标系,这一点很重要,不了解清楚可能做出来的效果面目全非,别问我怎么知道的。。。。

    上述不清楚的,或者想要深入学习自定义View的,推荐大家去 扔物线大大的 HenCoder 专栏学习一波

  • 简要流程图
    就简单解释一下旋转到90度时的处理流程(没找到方便的画图软件,很难受,读者有合适的给推荐一哈啊~)

    1. 图一为正常状态下的坐标系,灰色部分表示当前canvas
    2. 图二:假定此时进行到动画2,且旋转到90度,canvas的坐标系旋转90度,然后绕camera的y轴旋转一定角度,应用到canvas后,canvas变为图中红+粉色那个样子(现需要注意二者坐标系,图中仅仅标识canvas的坐标系)
    3. 然而我们只需要翻折的那部分用来绘制翻折起来的图片,因此对红色部分进行裁切。
    4. 图三:而由于我们原本的图片是不进行旋转的,因此我们需要将坐标系还原回来,这样我们绘制图片时候,就只会在红色翻折起来的canvas中绘制。

    剩下的另一半原理也是一样的,大家自己脑补吧。。

    (不知道合适的绘图软件,用windows自带的画图实在太难受。。)

实现

Demo地址 FilpboardAnimation

直接放代码吧,注释比较详细,对比上面的分析,不难理解。

MapView.java

public class MapView extends View {//“右侧” 沿Y轴翻折的角度private float degreeY;//canvas 旋转的角度private float degreeZ;//“左侧” 最后翻折的角度private float fixY;private Paint mPaint;private Bitmap mBitmap;private Camera mCamera;public MapView(Context context) {this(context,null);}public MapView(Context context, @Nullable AttributeSet attrs) {this(context, attrs,0);}public MapView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);TypedArray a = context.obtainStyledAttributes(attrs,R.styleable.MapView);BitmapDrawable drawable = (BitmapDrawable) a.getDrawable(R.styleable.MapView_mv_background);a.recycle();if (drawable!=null){mBitmap = drawable.getBitmap();}else {mBitmap = BitmapFactory.decodeResource(getResources(),R.drawable.flip_board);}mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);mCamera = new Camera();//沿Z轴平移,防止相机旋转后图片“糊”到脸上DisplayMetrics displayMetrics = getResources().getDisplayMetrics();float newZ = - displayMetrics.density * 6;mCamera.setLocation(0,0,newZ);}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);int bitmapWidth = mBitmap.getWidth();int bitmapHeight = mBitmap.getHeight();int centerX = getWidth()/2;int centerY = getHeight()/2;//绘制 翻折&旋转 部分canvas.save();mCamera.save();canvas.translate(centerX,centerY);//画布移动到屏幕中心//“折线及翻折部分的画布” 的旋转canvas.rotate(-degreeZ);//画布旋转mCamera.rotateY(degreeY);//相机绕Y周旋转mCamera.applyToCanvas(canvas);//相机应用到画布canvas.clipRect(0,-centerY,centerX,centerY);//画布裁切,只绘制翻折起来的部分//因为翻折部分相对于画布而言,坐标始终未改变canvas.rotate(degreeZ);//将画布旋转为原角度,否则绘制时绘制的图片也会旋转mCamera.restore();canvas.drawBitmap(mBitmap,-bitmapWidth/2,-bitmapHeight/2,mPaint);//绘制图片,注意坐标canvas.restore();//绘制 剩余 部分canvas.save();mCamera.save();canvas.translate(centerX,centerY);//移动到画布中心//“折线以及最后才翻折的画布”的旋转canvas.rotate(-degreeZ);//画布旋转canvas.clipRect(-centerX,-centerY,0,centerY);//裁切绘制范围mCamera.rotateY(fixY);//将旋转之后才需要翻折的部分 进行旋转mCamera.applyToCanvas(canvas);canvas.rotate(degreeZ);//画布还原回原本角度mCamera.restore();canvas.drawBitmap(mBitmap,-bitmapWidth/2,-bitmapHeight/2,mPaint);//绘制图片,注意坐标canvas.restore();}public void reset(){degreeY = 0;degreeZ = 0;fixY = 0;}public void setDegreeY(float degreeY) {this.degreeY = degreeY;invalidate();}public void setDegreeZ(float degreeZ) {this.degreeZ = degreeZ;invalidate();}public void setFixY(float fixY) {this.fixY = fixY;invalidate();}}

MainActivity.java

public class MainActivity extends AppCompatActivity {MapView mMapView;private Handler mHandler = new Handler();@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);mMapView = findViewById(R.id.map_view);//三段动画//1."右侧" 翻折,"左侧" 不动//2."右侧" 旋转,"左侧" 配合旋转//3.收尾 "左侧" 翻折,"右侧" 不动ObjectAnimator animator1 = ObjectAnimator.ofFloat(mMapView,"degreeY",0,-45);animator1.setDuration(1000);animator1.setStartDelay(500);ObjectAnimator animator2 = ObjectAnimator.ofFloat(mMapView,"degreeZ",0,270);animator2.setDuration(800);animator2.setStartDelay(500);ObjectAnimator animator3 = ObjectAnimator.ofFloat(mMapView,"fixY",0,30);animator3.setDuration(500);animator3.setStartDelay(500);final AnimatorSet animatorSet = new AnimatorSet();//循环播放animatorSet.addListener(new AnimatorListenerAdapter() {@Overridepublic void onAnimationEnd(Animator animation) {super.onAnimationEnd(animation);/*//用handler的目的在这里只是为了模拟 原图中,在动画最后短暂停留mHandler.postDelayed(new Runnable() {@Overridepublic void run() {runOnUiThread(new Runnable() {@Overridepublic void run() {*///将属性重置mMapView.reset();animatorSet.start();}});/*}},500);}});*///顺序播放动画animatorSet.playSequentially(animator1,animator2,animator3);animatorSet.start();}
}

效果如下
Android studio自带的模拟器在我电脑里超级卡,录屏瑕疵很大,大家随便看一看就好

建议大家自己实现一下,运行看看实际效果,虽然东西虽小,但成就感还是很重要的不是么,哈哈~

好了,效果实现了,本文也就到此结束了。


总结

  • 本文仿写了一个简易的Flipboard翻页效果,后续可能仿写其他常用不常用的view,望多多支持。
  • 笔者水平有限,如有错漏,欢迎指正。
  • 接下来我也会将所学的知识分享出来,有兴趣可以继续关注whd_Alive的Android开发笔记
  • 不定期分享Android开发相关的技术干货,期待与你的交流,共勉。

教你仿写 Flipboard 的翻页效果相关推荐

  1. flipboard的翻页效果的实现

    最近看到flipboard的翻页效果很不错,就想着把他给实现,整个效果做的差不多了,还有一些细节要完善,现在放上来.我学android全靠自学的,而且的代码的质量也难保证,还希望各位大神批评指正那. ...

  2. 用jQuery写的一个翻页,并封装为插件,

    用jQuery写的一个翻页,并封装为插件, 1 *{ 2 margin:0; 3 padding: 0; 4 list-style: none; 5 text-decoration: none; 6 ...

  3. 2012-01-10 自己写的基于jquery的翻页效果

    是不是啊~~这么一转眼,四个月就没了~~~身为码农的我.哎..  加油吧... 正文:     一个好看的用jquery做的打招呼  (第一次自己写啊,里面的翻页效果,初级初级~~呵呵) 首页 这个设 ...

  4. Ios 仿ibooks 翻页效果

    仿 ibooks 的翻页效果, 可对 pdf, 图片和一般视图 翻页. 来源: appdoll.com

  5. Android 使用ViewPager2+ExoPlayer+VideoCache 实现仿抖音视频翻页播放

    1. 实现效果 效果图中,视频没有铺满 是因为使用了ExoPlayer的RESIZE_MODE_FIT模式, 虽然使用RESIZE_MODE_FILL模式可以填充整个父布局,但是本Demo中使用的视频 ...

  6. 教你打造Silverlight超酷翻页实例

    经常阅读电子杂志的朋友对其流畅自然的翻页过渡效果应当留下了十分深刻的印象.这些杂志都是使用Flash技术制作而成的.总想着能用Silverlight实现这样的效果,去网上查查资料,找到了一个微软官方提 ...

  7. 优雅的时钟翻页效果,让你的网页时钟与众不同!

    你有没有想过给你的网页时钟添加翻页效果,让它更引人注目,更酷炫吗?如果是的话,你来对地方了! 子辰这篇文章将教你如何通过简单的步骤,为你的网页时钟添加翻页效果. 无论你是 web 开发初学者或是有一定 ...

  8. 用AjaxPro实现无刷新翻页效果及数据库分页技术介绍

    在看本文之前,建议查看本人的系列文章: <AjaxPro与服务器端交互过程中如何传值>:http://blog.csdn.net/zhoufoxcn/archive/2008/01/05/ ...

  9. Android之实现上下左右翻页效果

    如果实现上下或者左右翻页效果,我们借助下这个开源项目:https://github.com/openaphid/android-flip Aphid FlipView是一个能够实现Flipboard翻 ...

最新文章

  1. Cisco IOS版本命名规范
  2. 需要更换手机了:由 TensorFlow Lite 构建无人驾驶微型汽车
  3. python中sys.stdout、sys.stdin
  4. mysql监控nginx_mysql和nginx服务是否正常监控脚本
  5. 客户端连接caching-sha2-password 报错问题
  6. 线索二叉树原理及前序、中序线索化(Java版)
  7. linux中特殊字符的含义,Linux中的特殊符号以及特殊语法
  8. oracle stream 主键,oracle stream配置向导
  9. linux网卡握手速率模式,一种基于Linux平台下的网卡速率和双工模式测试的方法与流程...
  10. redhat6与7版本进入单用户模式修改root账户密码
  11. 浙江大学 PTA习题3.6 一元多项式的乘法与加法运算 (20分)
  12. ssis for循环容器_SSIS包中的序列容器
  13. php 字符串长度的解释
  14. VS2013编译eXosip2-5.0.0
  15. itest监考机制_iTEST系统
  16. 20 | 幻读是什么,幻读有什么问题?
  17. (Tiled官方文档翻译)第四节:对象的编辑和使用
  18. 扫描远程服务器开放端口
  19. 代数结构:群、环、域、模、线性空间、格
  20. 记一次tomcat、gateway配置SSL,使用https访问

热门文章

  1. 数据结构-算法与算法描述
  2. 纺织服装业如何利用技术进行数字化转型
  3. Java银行储户后台系统
  4. RNA-seq 详细教程:分析流程介绍(1)
  5. 深入浅出剖析JAVA多线程原理
  6. 合上笔记本屏幕 Ubuntu 20.04 不休眠
  7. 览书记之汽车电子信息技术
  8. 电脑开两个及以上微信
  9. moTzxx-CMS —— [一个基于PHP代码的后台管理系统(ThinkPHP5.1.40)]
  10. 爬虫爬取二次元网站美女图片