关键词:
前言
- 自定义
View
是Android
开发者必须了解的基础 - 网上有大量关于自定义
View
原理的文章,但存在一些问题:内容不全、思路不清晰、无源码分析、简单问题复杂化等等 - 今天,我将全面总结自定义
View
的原理,我能保证这是市面上的最全面、最清晰、最易懂的
- 本文秉着“结论先行、详细分析在后”的原则,即先让大家感性认识,再通过理性分析从而理解问题;
- 所以,请各位读者先记住结论,再往下继续看分析;
- 文章较长,阅读需要较长时间,建议收藏等充足时间再进行阅读
Carson带你学Android自定义View文章系列:
Carson带你学Android:自定义View基础
Carson带你学Android:一文梳理自定义View工作流程
Carson带你学Android:自定义View Measure过程
Carson带你学Android:自定义View Layout过程
Carson带你学Android:自定义View Draw过程
Carson带你学Android:手把手教你写一个完整的自定义View
Carson带你学Android:Canvas类全面解析
Carson带你学Android:Path类全面解析
目录
1. 储备知识
1.1 ViewRoot
-
定义
连接器,对应于ViewRootImpl
类 -
作用
- 连接
WindowManager
和DecorView
- 完成
View
的三大流程:measure
、layout
、draw
- 连接
-
特别注意
// 在主线程中,Activity对象被创建后:
// 1. 自动将DecorView添加到Window中 & 创建ViewRootImpll对象
root = new ViewRootImpl(view.getContent(),display);
// 3. 将ViewRootImpll对象与DecorView建立关联
root.setView(view,wparams,panelParentView)
1.2 DecorView
- 定义:顶层
View
即
Android
视图树的根节点;同时也是FrameLayout
的子类
- 作用:显示 & 加载布局
View
层的事件都先经过DecorView
,再传递到View
- 特别说明
内含1个竖直方向的LinearLayout
,分为2部分:上 = 标题栏(titlebar)
、下 = 内容栏(content)
在
Activity
中通过setContentView()
所设置的布局文件其实是被加到内容栏之中的,成为其唯一子View = id为content的FrameLayout
中
// 在代码中可通过content得到对应加载的布局
// 1. 得到content
ViewGroup content = (ViewGroup)findViewById(android.R.id.content);
// 2. 得到设置的View
ViewGroup rootView = (ViewGroup) content.getChildAt(0);
1.3 Window、Activity、DecorView 与 ViewRoot的关系
- 简介
-
之间的关系
-
更加详细 & 具体的介绍,请看文章:Android自定义View基础:ViewRoot、DecorView & Window的简介
1.4 自定义View基础
了解自定义View流程前,需了解一定的自定义View基础,具体请看文章:Carson带你学Android:自定义View基础
2. 绘制准备
-
回忆上图,可看出最后1步 = 绘制
-
但在绘制前,系统会有一些绘制准备,即前面几个步骤:创建
PhoneWindow
类、DecorView
类、ViewRootmpl
类等
故,下面我会先将绘制前的准备,再开始讲绘制流程
- 主要包括:
DecorView
创建 & 显示,具体请看文章:Android自定义View绘制前的准备:DecorView创建 & 显示
3. 绘制流程概述
- 从上可知,
View
的绘制流程开始于:ViewRootImpl
对象的performTraversals()
- 源码分析
/**
* 源码分析:ViewRootImpl.performTraversals()
*/
private void performTraversals()
// 1. 执行measure流程
// 内部会调用performMeasure()
measureHierarchy(host, lp, res,desiredWindowWidth, desiredWindowHeight);
// 2. 执行layout流程
performLayout(lp, mWidth, mHeight);
// 3. 执行draw流程
performDraw();
- 从上面的
performTraversals()
可知:View
的绘制流程从顶级View(DecorView)
的ViewGroup
开始,一层一层从ViewGroup
至子View
遍历测绘
即:自上而下遍历、由父视图到子视图、每一个
ViewGroup
负责测绘它所有的子视图,而最底层的 View 会负责测绘自身
- 绘制的流程 =
measure
过程、layout
过程、draw
过程,具体如下
下面,我将详细讲解View
绘制的三大流程:measure
过程、layout
过程、draw
过程
4. 详细介绍
4.1 Measure 过程
- 作用
测量View
的宽 / 高
- 在某些情况下,需要多次测量
(measure)
才能确定View
最终的宽/高;- 该情况下,
measure
过程后得到的宽 / 高可能不准确;- 此处建议:在
layout
过程中onLayout()
去获取最终的宽 / 高
- 具体流程
- 详细讲解
请看文章:Carson带你学Android:自定义View Measure过程
4.2 Layout过程
- 作用
计算视图(View)
的位置
即计算
View
的四个顶点位置:Left
、Top
、Right
和Bottom
- 具体流程
- 详细讲解
请看文章:Carson带你学Android:自定义View Layout过程
4.3 Draw过程
-
作用
绘制View
视图 -
具体流程
- 详细讲解
请看文章:Carson带你学Android:自定义View Draw过程
至此,关于自定义View
的工作流程讲解完毕。
5. 自定义View的步骤
步骤1:实现Measure、Layout、Draw流程
- 从View的工作流程(
measure
过程、layout
过程、draw
过程)来看,若要实现自定义View
,根据自定义View的种类不同(单一View
/ViewGroup
),需自定义实现不同的方法 - 主要是:
onMeasure()
、onLayout()
、onDraw()
,具体如下
步骤2:自定义属性
- 在values目录下创建自定义属性的xml文件
- 在自定义View的构造方法中加载自定义XML文件 & 解析属性值
- 在布局文件中使用自定义属性
6. 实例讲解
结合原理 & 实现步骤,若需实现1个自定义View,请看文章:Carson带你学Android:手把手教你写一个完整的自定义View
7. 总结
- 本文全面总结自定义
View
的原理。至此,关于自定义View
的绘制流程您应该非常熟悉了 - Carson带你学Android自定义View文章系列:
Carson带你学Android:自定义View基础
Carson带你学Android:一文梳理自定义View工作流程
Carson带你学Android:自定义View Measure过程
Carson带你学Android:自定义View Layout过程
Carson带你学Android:自定义View Draw过程
Carson带你学Android:手把手教你写一个完整的自定义View
Carson带你学Android:Canvas类全面解析
Carson带你学Android:Path类全面解析
欢迎关注Carson_Ho的CSDN博客 与 公众号!
博客链接:https://carsonho.blog.csdn.net/
请帮顶 / 评论点赞!因为你的鼓励是我写作的最大动力!
carson带你学序列化:深入分析xml多种解析方式(domsaxpull)(代码片段)
...关于另外1种主流的数据传输格式JSON,具体请看:Carson带你学序列化:深入分析JSON多种解析方式(Gson、AS自带org.json、Jackson)2.作用对数据进行标记(结构化数据) 查看详情
carson带你学java:深入解析引用类型-强软弱虚(代码片段)
前言在Java中,对象的引用类型十分重要,因为这取决于JVM的GC活动&活动本文全面&详细解析Java的4种引用类型:强引用、软引用、弱引用、虚引用,希望您们会喜欢目录1.简介JDK1.2前,Java的引用类型只有2... 查看详情
carson带你学android:这是一份详细的retrofit使用教程(含实例讲解)(代码片段)
前言在Andrroid开发中,网络请求十分常用而在Android网络请求库中,Retrofit是当下最热的一个网络请求库今天,我将献上一份非常详细Retrofitv2.0的使用教程,希望你们会喜欢。如果对Retrofitv2.0的源码感兴趣,可看... 查看详情
carson带你学android:手把手带你全面学习补间动画的使用!(代码片段)
前言动画的使用是Android开发中常用的知识今天,我将将献上一份Android补间动画的使用教程,手把手教你使用补间动画。Carson带你学Android动画系列文章:Carson带你学Android:一份全面&详细的动画知识学习攻略Cars... 查看详情
carson带你学android:手把手带你全面学习补间动画的使用!(代码片段)
前言动画的使用是Android开发中常用的知识今天,我将将献上一份Android补间动画的使用教程,手把手教你使用补间动画。Carson带你学Android动画系列文章:Carson带你学Android:一份全面&详细的动画知识学习攻略Cars... 查看详情
carson带你学android:手把手带你全面学习补间动画的使用!(代码片段)
前言动画的使用是Android开发中常用的知识今天,我将将献上一份Android补间动画的使用教程,手把手教你使用补间动画。Carson带你学Android动画系列文章:Carson带你学Android:一份全面&详细的动画知识学习攻略Cars... 查看详情
carson带你学android:常见的动画类型你知多少?(代码片段)
前言动画的使用是Android开发中常用的知识可是动画的种类繁多、使用复杂,每当需要采用自定义动画实现复杂的动画效果时,很多开发者就显得束手无策本文将献上一份Android动画简介,包括动画的种类、使用、原理... 查看详情
carson带你学android:手把手教你写一个完整的自定义view
参考技术A自定义View一共分为两大类,具体如下图:对于自定义View的类型介绍及使用场景如下图:在使用自定义View时有很多注意点(坑),希望大家要非常留意:View的内部本身提供了post系列的方法,完全可以替代Handler的作用... 查看详情
carson带你学android:最全面的webview使用详解(代码片段)
...等等,如下图那么这种该如何实现呢?其实这是Android里一个叫WebView的组件实现的。今天我将全面介绍WebView的常用用法。Carson带你学WebView系列文章Carson带你学Androidÿ 查看详情
carson带你学android:你要的webview与js交互方式都在这里了(代码片段)
...#xff0c;淘宝、京东、聚划算等等,如下图上述功能是由Android的WebView实现的,其中涉及到Android客户端与Web网页交互的实现今天我将全面介绍Android通过WebView与JS交互的全面方式Carson带你学WebView系列文章Carson带你学Android:... 查看详情
carson带你学android:这是一个与众不同的android微信公众号(代码片段)
前言今天,我想向广大Android开发者介绍一个与众不同、有特色的Android微信公众号,希望你们会喜欢。注:我是本Android微信公众号的运营者carson_ho,简单介绍如下:附:各大技术社区的个人链接CSDN:htt... 查看详情
carson带你学java:深入解析引用类型-强软弱虚(代码片段)
前言在Java中,对象的引用类型十分重要,因为这取决于JVM的GC活动&活动本文全面&详细解析Java的4种引用类型:强引用、软引用、弱引用、虚引用,希望您们会喜欢目录1.简介JDK1.2前,Java的引用类型只有2... 查看详情
carson带你学java:深入解析引用类型-强软弱虚(代码片段)
前言在Java中,对象的引用类型十分重要,因为这取决于JVM的GC活动&活动本文全面&详细解析Java的4种引用类型:强引用、软引用、弱引用、虚引用,希望您们会喜欢目录1.简介JDK1.2前,Java的引用类型只有2... 查看详情
carson带你学android:手把手带你入门神秘的rxjava(代码片段)
...链式调用、逻辑简洁&使用简单的特点,深受各大Android开发者的欢迎。本文主要:面向刚接触Rxjava的初学者提供了一份清晰、简洁、易懂的Rxjava入门教程涵盖基本介绍、原理&具体使用等解决的是初学者不理解Rxjava原... 查看详情
carson带你学设计模式:单例模式(singleton)(代码片段)
前言今天Carson来全面总结最常用的设计模式-单例模式。Carson带你学设计模式系列文章Carson带你学设计模式:这是一份全面&详细的设计模式学习指南Carson带你学设计模式:单例模式(Singleton)Carson带你学设计模... 查看详情
carson带你学设计模式:观察者模式(observer)(代码片段)
前言今天Carson来全面总结最常用的设计模式-观察者模式(Observer)。Carson带你学设计模式系列文章Carson带你学设计模式:这是一份全面&详细的设计模式学习指南Carson带你学设计模式:单例模式(Singleton... 查看详情
carson带你学java:泛型知识知多少(代码片段)
目录定义意义(即为什么要使用泛型)作用及特点原理额外说明:List能否转为List?定义可理解为适配广泛的类型,即参数化类型,可以把类型像方法的参数那样进行传递。//以ArrayList为示例//泛型T可以是... 查看详情
carson带你学设计模式:这是一份全面&详细的设计模式学习指南
前言设计模式其实并不神秘,今天carson将带你了解一切关于设计模式的知识。Carson带你学设计模式系列文章Carson带你学设计模式:这是一份全面&详细的设计模式学习指南Carson带你学设计模式:单例模式(Singleto... 查看详情