float 表示浮点值
fraction 表示百分数
enum 表示枚举值
flag 表示位运算
–>
-
attrs.xml文件declare-styleable标签定义及相关属性
-
在布局文件中导入自定义的属性集。两种方法
xmlns:custom=“http://schemas.android.com/apk/res/com.example”
xmlns:custom=“http://schemas.android.com/apk/res-auto”
- 代码中如何获取自定义属性值
TypedArray arry = context.obtainStyledAttributes(attrs, R.styleable.CustomView);
float size = arry.getDimension(R.styleable.CustomView_size,10f);
// to use
ViewGroup绘制流程
View和ViewGroup绘制流程基本相同,只是ViewGroup除了绘制自己还需要绘制子控件。绘制流程分为测量 ——布局——绘制 主要对应下面三个函数:
-
onMeasure():测量当前控件大小并为布局提供建议
-
onLayout():使用layout()函数对所有子控件进行布局
-
onDraw():根据测量布局的位置绘图
measure流程和MeasureSpec
MeasureSpec是int型数字,但它由两部分组成mode+size,它转换为二进制前两位代表模式后30位代表数值,它有三种模式。MeasureSpec是View的内部类,作用是在Measure的过程中,将View的LayoutParams根据父容器所分发的规则转换成对应的MeasureSpec,最后在onMeasure根据该值确定View的宽高。
-
UNSPECIFIED: 未指定模式,子View不受父View的限制,子View可以设置任意大小。一般用于系统内部的测量。
-
EXACTLY:精确模式,对应于match_parent和具体数值,子元素被限定于给定的边界。
-
AT_MOST:最大模式,对应于wrap_content,父控件给子控件分配的SpecSize。
作为顶层的View,它没有父容器。DecorView的getRootMeasureSpec方法第一个参数windowSize是指窗口尺寸,它的MeasureSpec由自身的LayoutParams和窗口尺寸大小决定。
特别需要注意的是,wrap_content对应AT_MOST,当布局文件中配置为EXACTLY模式时,我们就直接使用该值即可,当模式为AT_MOST,我们还需要将大小设置为我们计算的值,该值应该是包含控件最大值。
View的measure流程 : 先判断有无背景,取mMinWidth和背景的最小宽度的最大值; 再通过measureSpec获取默认大小
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec),
getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec));
}
public static int getDefaultSize(int size, int measureSpec) {
int result = size;
int specMode = MeasureSpec.getMode(measureSpec);
int specSize = MeasureSpec.getSize(measureSpec);
switch (specMode) {
case MeasureSpec.UNSPECIFIED:
result = size;
break;
case MeasureSpec.AT_MOST:
case MeasureSpec.EXACTLY:
result = specSize;
break;
}
return result;
}
protected int getSuggestedMinimumWidth() {
return (mBackground == null) ? mMinWidth : max(mMinWidth, mBackground.getMinimumWidth());
}
ViewGroup源码中无onMeasure方法,它的measure流程 :直接遍历测量子View的MeasureSpec,measureChild中则是先获取自己的LayoutParams ,再计算自己的getChildMeasureSpec。
protected void measureChildren(int widthMeasureSpec, int heightMeasureSpec) {
final int size = mChildrenCount;
final View[] children = mChildren;
for (int i = 0; i < size; ++i) {
final View child = children[i];
if ((child.mViewFlags & VISIBILITY_MASK) != GONE) {
measureChild(child, widthMeasureSpec, heightMeasureSpec);
}
}
}
protected void measureChild(View child, int parentWidthMeasureSpec,
int parentHeightMeasureSpec) {
final LayoutParams lp = child.getLayoutParams();
final int childWidthMeasureSpec = getChildMeasureSpec(parentWidthMeasureSpec,
mPaddingLeft + mPaddingRight, lp.width);
final int childHeightMeasureSpec = getChildMeasureSpec(parentHeightMeasureSpec,
mPaddingTop + mPaddingBottom, lp.height);
child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
}
layout流程
View中的layout是用来确定自身的位置。调用层级是layout调用setFrame确定该View在父容器中的位置,最后才调用onLayout。
ViewGroup的layout则是用来确定子元素的位置,不通的布局有不同的摆放规则,但都离不开最终调用setChirdFrame方法,调用子View的layout方法确定子View的位置。为了满足多种需求,我们有时还需要获取子View的MarginLayoutParams和重写generateLayoutParams提取Margin值。
draw流程
-
如果需要绘制背景
-
保存当前canvas层
-
绘制View的内容,即onDraw()方法 是一个空实现由我们自己实现
-
绘制子View,调用dispatchDraw()对子View遍历,子View绘制
-
如果需要绘制View的褪色边缘,类似于阴影效果
-
绘制装饰,如滚动条。onDrawForeground()方法
注:getMeasuredWidth()和getWidth()函数的区别
他们大多时候是相同的,但含义是不一样的。getMeasuredWidth一般被调用在layout中,getWidth则被调用在onDraw中。我们时常会在onDraw混用两个方法,切记用错。
-
getMeasuredWidth()函数在measure过程结束后就可以获取到,而getWidth()需要layout结束后才能获取到。
-
getMeasuredWidth()的值时通过setMeasuredDimension()进行设置的,getWidth()是通过layout(left,top,right,bottom)函数设置。
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则近万的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:Android)
【附】相关架构及资料
往期Android高级架构资料、源码、笔记、视频。高级UI、性能优化、架构师课程、NDK、混合式开发(ReactNative+Weex)微信小程序、Flutter全方面的Android进阶实践技术,群内还有技术大牛一起讨论交流解决问题。
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!
mg-UXxEd6xd-1713782545779)]
往期Android高级架构资料、源码、笔记、视频。高级UI、性能优化、架构师课程、NDK、混合式开发(ReactNative+Weex)微信小程序、Flutter全方面的Android进阶实践技术,群内还有技术大牛一起讨论交流解决问题。
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!