自定义View从入门到懵逼系列(下)
来源:互联网 发布:算卦一条街源码 编辑:程序博客网 时间:2024/05/21 16:01
传送门
系列文章传送门
自定义View从入门到懵逼系列(上)
自定义View从入门到懵逼系列(下)
GitHub自定义View的Demo
这篇是笔记中的下篇,包含的主要内容有:Paint类、绘制顺序、属性动画、自定义View的分类和流程概述、事件的分发、滑动冲突。
1. Paint类(画笔)
我们在上篇中着重讲了绘制类Canvas的一些操作属性,我们知道单单有画布是远远不够的,还有重要的就是我们需要一个画笔用来在画布上绘制东西,所以Paint类就是Android的画笔。
除了最普通的操作对画笔上色调用setColor、setAGB这些操作,画笔对颜色的处理还有其他两个重要操作,Shader着色器和ColorFilter。
1.1 颜色-Shader着色器
5种:LinearGradient(线性渐变)、RadialGradient(辐射渐变)、SweepGradient(扫描渐变)、BitmapShader、ComposeShader(混合着色器)。
1.2 颜色-ColorFilter过滤器
LightingColorFilter,对各个色值进行调节;
ColorMatrixColorFilter,设置饱和度等。
1.3 Xfermode
其实就是要你以绘制的内容作为源图像,以 View 中已有的内容作为目标图像,选取一个 PorterDuff.Mode 作为绘制内容的颜色处理方案,离屏缓存。
1.4 效果
抗锯齿、填充风格、宽度、线头形状、拐角形状等属性。
1.5 色彩优化
抖动、双线性过滤
1.6 轮廓-PathEffect
CornerPathEffect,所有拐角变成圆角;
DiscretePathEffect,线条进行随机的偏离;
DashPathEffect,虚线来绘制线条;
PathDashPathEffect,使用一个 Path 来绘制「虚线」;
SumPathEffect,组合分别绘制;
ComposePathEffect,合并绘制;
1.7 阴影
setShadowLayer、setMaskFilter
2. 绘制顺序
3. 属性动画Property Animation
3.1 简介
动画包含Animation、Transition两种;
Animation包含视图动画ViewAnimation和属性动画PropertyAnimation;
Transition是过渡,一般不用;
我们99%的场合用的都是PropertyAnimation属性动画,属性动画分为两种,ViewPropertyAnimator和ObjectPropertyAnimator。
3.2 ViewPropertyAnimator
用法直接拿View.animate().xxx使用即可,但是仅限于以下的这些方法,不可自定义。
3.3 ObjectPropertyAnimator
ObjectPropertyAnimator比ViewPropertyAnimator高级,它不仅可以使用提供的api,还能根据自己的需求自定义View的属性,一般分为三步。
1.如果是自定义控件,需要添加 setter / getter 方法;
2.用 ObjectAnimator.ofXXX() 创建 ObjectAnimator 对象;
3.用 start() 方法执行动画。
比如我们画一个圆环,百分比进度用float progress来表示,我们就可以用ObjectPropertyAnimator来展示动画。
3.4 插值器Interpolator
有多种插值器。
3.5 多动画执行
PropertyValuesHolder同时执行,AnimatorSet多动画根据设定顺序执行。
3.6 TypeEvaluator
自定义动画的属性,针对特殊属性来做属性动画,比如我们可以将Point来作为属性。
4. 自定义View的分类和流程概述
自定义View应该分为两类:
- 自定义ViewGroup,一般是利用现有的组件根据特定的布局方式来组成新的组件,大多继承自ViewGroup或各种Layout,包含有子View。
- 自定义View,在没有现成的View,需要自己实现的时候,就使用自定义View,一般继承自View,SurfaceView或其他的View,不包含子View。
4.1 测量View大小-onMeasure()
View的大小不仅由自身所决定,同时也会受到父控件的影响,为了我们的控件能更好的适应各种情况,一般会自己进行测量。
MeasureSpec中的Mode有三种:
- UNSPECIFIED,子View大小没有任何限制(0, +∞);
- EXACTLY,父控件明确地指定了子View的大小;
- AT_MOST,没有具体尺寸,但是最大为父控件大小(0, parentSize)。
4.2 确定View大小-onSizeChanged()
View的大小不仅由View本身控制,而且受父控件的影响,所以我们在确定View大小的时候最好使用系统提供的onSizeChanged回调函数。
4.3 确定子View布局的位置-onLayout()
确定布局的函数是onLayout,它用于确定子View的位置,在自定义ViewGroup中会用到,他调用的是子View的layout函数。
在自定义ViewGroup中,onLayout一般是循环取出子View,然后经过计算得出各个子View位置的坐标值,然后用以下函数设置子View位置。
child.layout(l, t, r, b);
4.4 绘制内容-onDraw()
onDraw是实际绘制的部分,也就是我们真正关心的部分,使用的是Canvas绘图。
5. 事件的分发
- 事件分发原理: 责任链模式,事件层层传递,直到被消费;
- View 的 dispatchTouchEvent 主要用于调度自身的监听器和 onTouchEvent;
- View的事件的调度顺序是 onTouchListener > onTouchEvent > onLongClickListener > onClickListener ;
- 不论 View 自身是否注册点击事件,只要 View 是可点击的就会消费事件;
- 事件是否被消费由返回值决定,true 表示消费,false 表示不消费,与是否使用了事件无关;
- ViewGroup 中可能有多个 ChildView 时,将事件分配给包含点击位置的 ChildView;
- ViewGroup 和 ChildView 同时注册了事件监听器(onClick等),由 ChildView 消费;
- 一次触摸流程中产生事件应被同一 View 消费,全部接收或者全部拒绝;
- 只要接受 ACTION_DOWN 就意味着接受所有的事件,拒绝 ACTION_DOWN 则不会收到后续内容;
- 如果当前正在处理的事件被上层 View 拦截,会收到一个 ACTION_CANCEL,后续事件不会再传递过来。
详细参考此文章
6. 滑动冲突
传送门
- 自定义View从入门到懵逼系列(下)
- 自定义View从入门到懵逼系列(上)
- Android从零开搞系列:自定义View(7)ScrollTo+ScrollBy+Scroller+NestedScrolling机制(下)
- Android从零开搞系列:自定义View(5)基本的自定义ViewPager指示器+开源项目分析(下)
- Android从零开搞系列:自定义View(1)setContent()台前幕后
- Android从零开搞系列:自定义View(8)Canvas解析
- 自定义View系列教程(从基础绘制讲起哦~~~~~~~)
- Android从零开搞系列:自定义View(15)仿天天美剧拖动卡片的效果(下)
- Android从零开搞系列:自定义View(16)自定义验证码输入框效果
- Android从零开搞系列:自定义View(6)ScrollTo+ScrollBy+Scroller+NestedScrolling机制(上)
- Android从零开搞系列:自定义View(9)事件分发+事件拦截(滑动冲突)
- Android从零开搞系列:自定义View(2)继承RecyclerView实现下拉刷新和加载更多
- Android从零开搞系列:自定义View(3)Canvas基本API+综合应用+开源分析
- Android从零开搞系列:自定义View(10)流式布局
- Android从零开搞系列:自定义View(11)使用ViewPager打造轮播广告条
- Android从零开搞系列:自定义View(12)贝塞尔曲线的应用
- Android从零开搞系列:自定义View(13)新消息小圆点效果
- Android从零开搞系列:自定义View(4)基本的自定义ViewPager指示器+开源项目分析(上)
- JAVASE(Date)
- 单点登录实现(spring session+redis完成session共享
- 欢迎使用CSDN-markdown编辑器
- JAVASE(replace)
- sphereface v2
- 自定义View从入门到懵逼系列(下)
- JAVASE(正则)
- iOS 给文字添加阴影
- JZOJsenior3485.【NOIP2013模拟联考10】独立集(bubble)
- 如何使用电脑扫描二维码
- 第四周【项目4
- Jetty官网下载(历史版本)
- JAVASE(字符串)
- Ubuntu安装Github