Android自定义控件开发入门与实战(4)属性动画(1)

openMenu();

} else {

mIsMenuOpen = false;

closeMenu();

}

}

private void openMenu() {

doAnimationOpen(mItemButton1, 0, 5, 300);

doAnimationOpen(mItemButton2, 1, 5, 300);

doAnimationOpen(mItemButton3, 2, 5, 300);

doAnimationOpen(mItemButton4, 3, 5, 300);

doAnimationOpen(mItemButton5, 4, 5, 300);

}

private void doAnimationOpen(View v, int index, int total, int radius) {

if (v.getVisibility() != View.VISIBLE) {

v.setVisibility(View.VISIBLE);

}

double degree = Math.toRadians(90) / (total - 1) * index;

int translationX = (int) -(radius * Math.sin(degree));

int translationY = (int) -(radius * Math.cos(degree));

AnimatorSet set = new AnimatorSet();

set.playTogether(ObjectAnimator.ofFloat(v, “translationX”, 0, translationX),

ObjectAnimator.ofFloat(v, “translationY”, 0, translationY),

ObjectAnimator.ofFloat(v, “scaleX”, 0f, 1f),

ObjectAnimator.ofFloat(v, “scaleY”, 0f, 1f),

ObjectAnimator.ofFloat(v, “alpha”, 0, 1));

set.setDuration(500).start();

set.addListener(new Animator.AnimatorListener() {

@Override

public void onAnimationStart(Animator animation) {

}

@Override

public void onAnimationEnd(Animator animation) {

v.setVisibility(View.INVISIBLE);

}

@Override

public void onAnimationCancel(Animator animation) {

}

@Override

public void onAnimationRepeat(Animator animation) {

}

});

}

private void closeMenu() {

doAnimationClose(mItemButton1, 0, 5, 300);

doAnimationClose(mItemButton2, 1, 5, 300);

doAnimationClose(mItemButton3, 2, 5, 300);

doAnimationClose(mItemButton4, 3, 5, 300);

doAnimationClose(mItemButton5, 4, 5, 300);

}

private void doAnimationClose(View v, int index, int total, int radius) {

if (v.getVisibility() != View.VISIBLE) {

v.setVisibility(View.VISIBLE);

}

double degree = Math.PI * index / ((total - 1) * 2);

int translationX = (int) -(radius * Math.sin(degree));

int translationY = (int) -(radius * Math.cos(degree));

AnimatorSet set = new AnimatorSet();

set.playTogether(ObjectAnimator.ofFloat(v, “translationX”, translationX, 0),

ObjectAnimator.ofFloat(v, “translationY”, translationY, 0),

ObjectAnimator.ofFloat(v, “scaleX”, 1f, 0f),

ObjectAnimator.ofFloat(v, “scaleY”, 1f, 0f),

ObjectAnimator.ofFloat(v, “alpha”, 1, 0));

set.setDuration(500).start();

}

Animator的XML实现

在XML中有Animator对应的三个标签

  1. < animator />:对应ValueAnimator

  2. < objectAnimator />:对应ObjectAnimator

  3. < set />:对应AnimatorSet

要将动画放在res/animator下:

在这里插入图片描述

这些值得定义为:

在这里插入图片描述

第四章、属性动画进阶


这一章开始就有很多我没有学过的知识啦。

4.1 PropertyValuesHolder与KeyFrame

ValueAnimator和ObjectAnimator除了上述那些创建Animator实例的函数意外。还都有一个函数:

public static ValueAnimator ofPropertyValuesHolder(PropertyValuesHolder…values)

public static ObjectAnimator ofPropertyValuesHolder(Object target,PropertyValuesHolder…values)

两个Animator都有这个函数,但一般而言,ValueAnimator使用的情况并不多,所以我们就看下ObjectAnimator中的ofPropertyValuesHolder。

ofPropetyValuesHolder

其含义就是:保存了动画过程中所需的操作和对应的值。我们通过ofFloat构造的动画,ofFloat函数的内部实现其实就是将传入的参数封装成PropetyValuesHolder实例来保存动画状态的。在封装成实例之后,后期的各种操作也是由ofPropetyValuesHolder为主的。

所以ObjectAnimator通过暴露出PropertyValuesHolder方法,我们就可以用它来构造动画。

通过PropetyValuesHolder实例的函数有以下几个:

public static PropertyValuesHolder ofFloat(String propertyName,float…values);

public static PropertyValuesHolder ofInt(String propertyName,int…values);

public static PropertyValuesHolder ofObject(String propertyName,TypeEvaluator evaluator,Object…values);

public static PropertyValuesHolder ofKeyframe(String propertyName,Keyframe…values);

  1. 关于PropertyValuesHolder的ofFloat和ofInt

就比ObjectAnimator中的ofFloat和ofInt少一个target

  1. 关于将PropertyValuesHolder设置到ObjectAnimator中

ObjectAnimator有个暴露的方法,所以我们可以将构造好的PropertyValuesHolder实例加入进去

ObjectAnimator.ofPropertyValuesHolder(Object target,PropertyValuesHolder …values)

如果传入多个实例,就会在targert上同时做多个操作。

最后

今天关于面试的分享就到这里,还是那句话,有些东西你不仅要懂,而且要能够很好地表达出来,能够让面试官认可你的理解,例如Handler机制,这个是面试必问之题。有些晦涩的点,或许它只活在面试当中,实际工作当中你压根不会用到它,但是你要知道它是什么东西。

最后在这里小编分享一份自己收录整理上述技术体系图相关的几十套腾讯、头条、阿里、美团等公司2021年的面试题,把技术点整理成了视频和PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节,由于篇幅有限,这里以图片的形式给大家展示一部分。

还有 高级架构技术进阶脑图、Android开发面试专题资料,高级进阶架构资料 帮助大家学习提升进阶,也节省大家在网上搜索资料的时间来学习,也可以分享给身边好友一起学习。

【Android核心高级技术PDF文档,BAT大厂面试真题解析】

【算法合集】

【延伸Android必备知识点】

【Android部分高级架构视频学习资源】

Android精讲视频领取学习后更加是如虎添翼!进军BATJ大厂等(备战)!现在都说互联网寒冬,其实无非就是你上错了车,且穿的少(技能),要是你上对车,自身技术能力够强,公司换掉的代价大,怎么可能会被裁掉,都是淘汰末端的业务Curd而已!现如今市场上初级程序员泛滥,这套教程针对Android开发工程师1-6年的人员、正处于瓶颈期,想要年后突破自己涨薪的,进阶Android中高级、架构师对你更是如鱼得水,赶快领取吧!
《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》点击传送门,即可获取!
如虎添翼!进军BATJ大厂等(备战)!现在都说互联网寒冬,其实无非就是你上错了车,且穿的少(技能),要是你上对车,自身技术能力够强,公司换掉的代价大,怎么可能会被裁掉,都是淘汰末端的业务Curd而已!现如今市场上初级程序员泛滥,这套教程针对Android开发工程师1-6年的人员、正处于瓶颈期,想要年后突破自己涨薪的,进阶Android中高级、架构师对你更是如鱼得水,赶快领取吧!
《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》点击传送门,即可获取!

  • 21
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
封面 1 序 2 捐助说明 5 目 录 7 第一章 View的绘图流程 12 1.1、概述 12 1.2、Activity的组成结构 13 1.3、View树的绘图流程 15 1.3.1 测量组件大小 16 1.3.2 确定子组件的位置 17 1.3.3 绘制组件 18 1.4、说点别的 22 1.5 练习作业 22 第二章 Graphics2D API 23 2.1、概述 23 2.2、Point类和PointF类 23 2.3、Rect类和RectF类 25 2.4、Bitmap类和BitmapDrawable类 32 2.5、Canvas类与Paint类 34 2.5.1 绘图概述 34 2.5.2 Paint类 34 2.5.3 Canvas类 39 2.6 练习作业 63 第三章 使用Graphics2D实现动态效果 64 3.1 概述 64 3.2 invalidate()方法 65 3.3 坐标转换 69 3.4 剪切区(Clip) 73 3.5 案例:指针走动的手表 82 3.6 练习作业 88 第四章 双缓存技术 89 4.1 双缓存 89 4.2 在屏幕上绘制曲线 90 4.3 在屏幕上绘制矩形 99 4.4 案例:绘图App 104 4.4.1 绘图属性 106 4.4.2 软件参数 108 4.4.3 绘图缓冲区 109 4.4.4 撤消操作 111 4.4.5 图形绘制 113 4.4.6 绘图区 118 4.4.7 主界面 119 4.5 练习作业 122 第五章 阴影、渐变和位图运算 123 5.1 概述 123 5.2 阴影 123 5.3 渐变 125 5.3.1 线性渐变(LinearGradient) 126 5.3.2 径向渐变(RadialGradient) 130 5.3.3 扫描渐变(SweepGradient) 135 5.3.4 位图渐变(BitmapShader) 138 5.3.5 混合渐变(ComposeShader) 140 5.3.6 渐变与Matrix 142 5.4 位图运算 143 5.4.1 PorterDuffXfermode 143 5.4.2 图层(Layer) 146 5.4.3 位图运算技巧 148 5.5 案例1:圆形头像 152 5.6 案例2:刮刮乐 156 5.7 练习作业 161 第六章 自定义组件 163 6.1 概述 163 6.2 自定义组件的基本结构 164 6.3 重写onMeasure方法 166 6.4 组件属性 175 6.4.1 属性的基本定义 175 6.4.2 读取来自style和theme中的属性 181 6.5 案例1:圆形ImageView组件 186 6.6 案例2:验证码组件CodeView 190 6.7 练习作业 202 第七章 自定义容器 204 7.1 概述 204 7.2 ViewGroup类 205 7.2.1 ViewGroup常用方法 205 7.2.2 ViewGroup的工作原理 208 7.2.3 重写onLayout()方法 213 7.3 CornerLayout布局 217 7.3.1 基本实现 217 7.3.2 内边距padding 224 7.3.3 外边距margin 228 7.3.4 自定义LayoutParams 238 7.4 案例:流式布局(FlowLayout) 246 7.5 练习作业 256 第八章 Scroller与平滑滚动 257 8.1 概述 257 8.2 认识scrollTo()和scrollBy()方法 258 8.3 Scroller类 264 8.4 平滑滚动的工作原理 271 8.5 案例:触摸滑屏 272 8.5.1 触摸滑屏的技术分析 272 8.5.2 速度跟踪器VelocityTracker 273 8.5.3 触摸滑屏的分步实现 274 8.6 练习作业 285 第九章 侧边栏 287 9.1 概述 287 9.2 使用二进制保存标识数据 289 9.2.1 位运算符 289 9.2.2 位运算的常用功能 292 9.3 继承自ViewGroup的侧边栏 293 9.4 继承自HorizontalScrollView的侧边栏 304 9.5 练习作业 312 第十章 加强版ListView 313 10.1 概述 313 10.2 ListView的基本使用 314 10.3 ListItem随手指左右滑动 318 10.4 向右滑动删除ListItem 326 10.5 滑动ListItem出现删除按钮 336 10.5.1 列表项专用容器ExtendLayout 337 10.5.2 列表项能滑出删除按钮的ListView 342 10.5.3 定义布局文件 350 10.5.4 显示ListView 351 10.6练习作业 353 案例代码说明 354

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值