Fighting!

潜行者的沉默

动画的种类

  1. 平移
  2. 透明
  3. 旋转
  4. 缩放
  5. 帧动画

动画的设计考虑

  1. 面向用户为开发者,因此API尽量简单
  2. 一个View有多个动画,但同时只能由一个运行
  3. 动画执行不能依赖于自身for循环
  4. 如何让动画动起来

动画任务

  1. 控件
  2. 时长
  3. 起始值
  4. 差值器

在属性动画初始化的的过程中

  1. 创建ObjectAnimator对象,保存控件及属性名,
  2. 设置关键帧的值,创建PropertyValueHolder, 通过KeyframeSet的ofInt方法将动画分解成不同的关键帧
  3. 创建关键帧,Keyframe保存了关键帧的mFraction比例,值没Value及值类型mValueType
  4. 估值器的设置,是用来计算关键帧之间具体的值,
  5. 差值器的设置是修改某个时间点动画的百分比

自定义控件开发思路

  1. 观察有哪些动画
  2. 哪些元素比较特别,后面有没有可能变更需求
  3. 看是否有事件交互
  4. 如何设置自定义控件较为合理

源码分析

事件分发的类型

down,move, up,cancel

事件分发序列

down -> up
down -> move -> up

事件分发的对象

Activity ViewGroup View

事件分发的方法

dispatchTouchEvent()
onInterceptTouchEvent()
onTouchEvent()

Activity的事件分发

  1. dispatchTouchEvent
  2. PhoneWindow.superDispatchTouchEvent()
  3. DecorView.superDispatchTouchEvent
  4. ViewGroup.dispatchTouchEvent
    事件由Activity到了ViewGroup,如果View没有消费掉,会调用Activity的onTouchEvent

ViewGroup的事件分发

  1. 事件从Down开始,接收到Down事件时会做取消并清除touch事件,置空mFistTouchTarget对象,清空Touch标记位
  2. 是否拦截判断(除Down时间以外),通过onIntercept,子类可以通过修改requestDisallowInteceptTouchEvent使父容器不拦截事件.默认都会走onInterceptTouchEvent方法,默认返回false
  3. 会调用dispatchTranseformdTouchEvent方法,内部会调用子类的dispatchTouchEvent方法或者父类的dispatchTouchEvent的方法

View中的事件处理

  1. 事件传递到中,会先发判断TouchListener,如果设置了TouchListener,根据回调方法onTouch方法的返回值,做响应处理,若返回true则进行第二步,否则第三步
  2. onTouch中返回true,则意味着事件被消费,onTouchEvent的方法将不再执行,事件结束
  3. onTouch中返回false,则意味着事件没有消费,将继续执行onTouchEvent方法
  4. onTouchEvent会更具事件类型执行不同的逻辑
  5. 当事件时down时,会判断是否设置了longClick事件,设置了则会更具到up的时长和longClick方法的返回值去决定是否执行onClickListener方法,修改OnLongClickListener方法的返回值可以使两个方法都执行

设计思想

架构设计思想的需求点

  1. 每个界面上的元素都需要有事件响应,那意味着事件的核心处理类不能太多
  2. 事件传递的工作不能丢给开发者,只暴露接口
  3. 每个控件都可以接受事件和消费事件,如果控件消费了,你那后续事件就交给这个事件了
  4. 如何查找会消费事件的控件
  5. 如何更具坐标查找该控件的范围
  6. 每次发生事件,都需要遍历每个子元素吗?
为什么所有的控件都继承字View

View是事件处理和传递的抽象类,还包括绘制,测量其他代码

事件分发的思考

  1. 容器包含很多子控件
  2. 子控件和容器都能消费事件
  3. 子控件不能进行分发给其他子控件
  4. 分发功能只能由容器分发给子控件

如何快速查找能响应的控件

TouchTarget消费对象的缓存队列的设计,利用链表及缓存池,通过链表操作达到复用的效果
obtain()方法,内部操作加锁,判断静态变量recycleBin缓存对象TouchTarget是否为空,不为空则取出第一个,否则new出一个TouchTarget.当一系列事件消费完后 ,释放这个对象加入缓存

Canvas绘制几何图形,文本,位图等

  1. drawBitmap() 在指定坐标绘制位图
  2. drawLine()根据起始点绘制连线
  3. drawPath()根据给定的路径,绘制连线
  4. drawPoint()根据给定的坐标,绘制点
  5. drawText()根据给定的坐标和文本绘制文字
    …..

位置,形状变化等

  1. void translate(float x, float y) 平移操作
  2. void scale() 缩放
  3. void rotate() 旋转
  4. void skew() 倾斜
  5. void clipXXX()剪切
  6. void clipOutXXX()反向剪切
  7. setMatrix(Matrix matrix) 通过matrix实现以上效果

Canvas的状态保存

Canvas内部维护着状态栈,通过save和restore保存恢复
离屏绘制saveLayer

Paint画笔

画笔的实现内部都是调用native方法的,画笔的基础Api

  1. setColor(Color.RED)
  2. setARGB(),setAlpha 设置颜色及透明度
  3. setAntiAlias(true) 抗锯齿
  4. setStyle() Paint.Style.STROKE/FILL/FILL_AND_STROKE 描边,填充效果
  5. setStrokeWidth() 描边宽度
  6. setStrokeCap() Paint.Cap.BUTT/ROUND/SQUARE 线尾部形状 默认BUTT,round圆角效果,方形
  7. setStrokeJoin() 拐角效果,MITER/ROUND/BEVEL 默认MITER尖角,圆角,折角
  8. setShader(Shader shader) 设置环形渲染器
  9. setXfermode() 设置图层混合模式
  10. setColorFilter()设置颜色过滤器
  11. setFilterBitmap(true) 设置双线性过滤,使图片更加平滑
  12. setMaskFilter() 设置画笔的遮罩滤镜
  13. setTextScalX(2) 设置缩放文本倍数
  14. setTextSize(38) 设置文本字体大小
  15. setTextAlign() 对齐方式
  16. setUnderLineText(true) 设置下划线
  17. getTextBounds(str, 0, str.length(), rect) 测量文本大小,将文本大小信息存放在rect中
  18. measureText(str) 测量文本的宽
  19. getFontMetrics()获取字体度量对象, 变量包括ascent,descent,top,bottom,leading ,字体的高度为descent - ascennt, leading为行间距是当前字的ascent - 上一个字的descent

setShader(Shader shader) 设置环形渲染器(着色器)

  1. LinearGradient 线性渲染
  2. RadilGradient 环形渲染
  3. SweepGradient 扫描渲染
  4. BitmapGradient 位图渲染
TileMode 平铺模式
  1. CLAMP 超出后 以最后像素拉升填充
  2. REPEAT 超出后重复平铺
  3. MIRROR 镜像填充

组合渲染器,图层混合模式Xfermode

PortorDuff.Mode

  1. 使用场景
    • ComposeShader 组合渲染器
    • Paint.setXfermode()
    • porterDuffColorFilter 颜色过滤器
  2. 使用注意
    • 静止硬件加速,14之后图层混合不支持硬件加速,但系统是默认打开的setLayerType(View.LAYER_SOFTWARE, null)
    • 离屏绘制,去除背景等其他干扰,保证xfermode不会出现错误结果saveLayer ,restoreToCount,

      setColorFilter

LightColorFilter
颜色过滤器,可以过滤掉指定颜色
PorterDuffFilter
颜色和其他的图层混合
颜色矩阵ColorMatrixColorFilter
通过修改颜色矩阵Matrix数组中的值

画笔滤镜总结

  1. 简单的模拟光照效果,可以使用LightColorFilter
  2. 图像与颜色的,图层混合的实现,PorterDuffColorFilter
  3. 颜色数组及颜色举证实现滤镜效果

PPT的学习记录

PPT学习之剪切

通过剪切可以得到一组图片,作为PPT的背景样式即板式,做到风格统一

PPT之基本四步骤

  1. 字体统一
  2. 突出标题
  3. 颜色取巧
  4. 配图

PPT之四大技能

  1. 复制
  2. 清除格式
  3. 更改图片
  4. PPT草稿

PPT之人物图片处理

  1. 聚焦脸部
  2. 圆形剪裁
  3. 图片装饰
  4. 去掉颜色

PPT之风格迥异的处理

  1. 调节大小,基准线
  2. 等比裁剪
  3. 横向分布
  4. 更换背景

源码总结

View是如何被添加到屏幕窗口上去的

  1. 在Activity的onCreate方法中调用setContentView将我们的布局传入
  2. 内部调用了Window的唯一实例对象PhoneWindow的setContentView方法
  3. 内部创建了顶层布局容器DecorView
  4. 在DecorView中加载了基础布局ViewGroup(主题布局),
  5. 将我们的布局添加到基础布局的FrameLayout中

View的绘制流程

  1. 绘制入口
    • ActivityThread.handlerResumeActivity
    • WindowManagerImpl.addView(decorView, layoutParams)
    • WindowManagerGlobal.addView()
  2. 绘制的类及方法
    • ViewRootImpl.addView(decorView, layoutParams, parentView)
    • ViewRootImpl.requestLayout()->scheduleTraversals()->doTraversals()->performTraversals()
  3. 绘制流程的三大步骤
    • ViewRootImpl.performMeasure()
    • ViewRootImpl.performLayout()
    • ViewRootImpl.performDraw
  4. 绘制中的测量
    • MeasureSpec的确定及计算: 顶层DecoView和其他View
    • DecorView通过窗口大小和DecoView本身大小确定
    • 其他View通过父View的MeasureSpec和本身的大小确定
  5. 绘制中的布局
    • view.layout的方法确定自身的位置
    • 若是ViewGroup类型,需要调用onLayout的方法确定子View的位置
  6. 绘制中的绘制
    • 绘制背景drawableBackground
    • 绘制自己onDraw
    • 绘制子View dispatchDraw
    • 绘制前景,滚动条装等饰

最后

onMeasure -> onLayout(ViewGroup要实现) -> onDraw(可选,系统控件不用实现)

VirtualAPK

是滴滴开源的插件化项目,实现动态加载和运行apk的功能。
支持任何class的加载,资源的加载及四大组件
架构图
android 插件化框架VitualAPK解析

0%