View 工作原理笔记整理

Android面试整理之UI部分——实现View的弹性滑动的三种方式(一) 一.使用Scroller   1.为什么有弹性滑动的需求?    用View提供的原生方法scrollTo/scrollBy,虽然是专用于View的滑动,操作简单,能比较方便地实现滑动效果并且不影响内部元素的单击事件,但,其不仅具有“只能滑动View的内容,并不能滑动View本身”的缺点,而且因为这个过程是瞬间完成的,这个没有过渡效果的滑动用户体验不好。因此,需要使用弹性滑动来实现过渡效果的 阅读详情

主要摘抄自:《Android 开发艺术探索》

参考文章:https://lrh1993.gitbooks.io/android_interview_guide/content/android/basis/custom_view.html


1、View 的工作流程

View 的工作流程主要指 measure(测量)、layout(布局)、draw(绘制)这三个流程。

DecorView 作为顶级 View,但是其会附属在 ViewRootImpl 上(即 ViewRoot)。

View 树的绘制流程从 ViewRootImpl#performTraversals() 开始,在该方法中,会依次调用 performMeasure()、performLayout()、performDraw() 来触发顶级 View 的测量、布局,以及绘制。

1.1 measure 过程

performMeasure() 方法中会直接调用 View#measure(),该方法为 final 类型的,在 measure() 中又会进一步调用 View#onMeasure()。

onMeasure() 的作用了是为了测量自身的尺寸,在该方法中,在测量出 width、height 之后,在其中调用setMeasuredDimension() 设定 View 的测量宽/高信息,完成 View 的测量操作(setMeasuredDimension() 方法必须在 onMeasure() 中主动调用,在 setMeasuredDimension() 方法调用之后,我们才能使用 getMeasuredWidth()和 getMeasuredHeight() 来获取视图测量出的宽高,以此之前调用这两个方法得到的值都会是 0)。

其中,对于 View 和 ViewGroup 来说,onMeasure() 的实现是有区别的。

  1. View 的 onMeasure() 只需要测量自身的尺寸,然后设定宽高即可;

  2. 而 ViewGroup 的 onMeasure() 方法一般需要根据布局特性进行重写,在里面需要依次测量子 View 的尺寸(即触发子 View 的 measure() 方法),可以通过调用默认的 measureChildren() 方法,或者手动遍历子 View 调用其 measure() 方法来实现。然后再根据子 View 的尺寸来计算自己的 测量尺寸,并设置自身的宽高(即手动调用 setMeasuredDimension() 方法)。
    而且,需要注意,在 ViewGroup 中调用子 View 的 measure() 时,需要 ViewGroup 自己根据 child 的 LayoutParams,以及自身的宽高来计算出 child 对应的 WidthMeasureSpec/HeightMeasureSpec(MeasureSpec 就包含了子 View 的 SpecMode 与 SpecSize),从而通过 child.measure() 传递进去。

1.2 layout 过程

performLayout() 方法中,会调用 View#layout() 方法(为 public 类型,可被重写),layout() 方法用于确定 View 本身的位置。

View#layout() 的大致流程如下:
(1)先直接或者间接的调用 setFrame() 方法,来设定 View 的四个顶点的位置(即 mLeft、mRight、mTop、mBottom),View 的四个顶点一旦确定,则 View 在父容器中的位置也就确定了。

(2)然后会调用 View#onLayout(),该方法用于确定子 View 的位置,在 View 中默认为空实现,而在 ViewGroup 中为抽象方法,需要 ViewGroup 的子类去实现。在实现的时候,需要根据布局的要求,结合子 View 的可见性进一步的调用子 View 的 layout() 方法。

需要注意的是,View 最终的大小是在 layout 阶段确定的,因此一个好的习惯是在 onLayout() 中去获取 View 的测量宽高或者最终宽高

1.3 draw 过程

performDraw() 方法中会进一步调用 draw() 方法,然后进一步调用 drawSoftware() 方法,在该方法中,会调用 View#draw(Canvas)。

在 View#draw(Canvas) 中会依次绘制如下内容:

  1. 绘制背景 drawBackground(canvas)
  2. 绘制自身的内容 onDraw(),默认空实现。而 ViewGroup 需要根据实际要求来决定是否重写该方法,但是作为控件容器,本身一般是没有内容的,此时就无须重写。
  3. 绘制子 View,通过dispatchDraw(),View 的该方法默认为空实现,而 ViewGroup 的有实现逻辑,其内部会通过调用 ViewGroup#drawChild() 间接调用 子 View 的 draw(Canvas, ViewGroup, long) 方法,该方法是让子 View 来绘制自己的(该方法是 View 基于 layer type 以及硬件加速来专门处理渲染行为的代码段),内部会在对应的情况调用 dispatchDraw() 或者 draw(Canvas)。
  4. 绘制装饰 onDrawForeground(),包括 ScrollIndicators、ScrollBars

还需要注意,View 有一个方法,setWillNotDraw(boolean willNotDraw),如果一个 View 不需要绘制任何内容(即无须用 onDraw() 绘制自身的内容),那么通过该方法将对应的标记位设置为 true 之后,系统会进行相应的优化。View 默认没有启用,ViewGroup 默认启用了(是在构造方法中,调用 initViewGroup() 方法时,在该方法中直接调用 setFlags(WILL_NOT_DRAW, DRAW_MASK) 设置的)。

该标记位的意义为:如果自定义的 ViewGroup 本身没有内容需要绘制的话,则可以启用该标记位。而当明确需要通过 onDraw() 来绘制内容的时候,则需要显示的关闭它。


2、自定义 View

2.1 四种实现途径:
  1. 继承 View 重写 onDraw()
  2. 继承 ViewGroup 派生特殊的 Layout
  3. 继承特定的 View(如 TextView)
  4. 继承特定的 ViewGroup
2.2 注意事项
  1. 让 View 支持 wrap_content
  2. 让 View 支持 padding,因为直接继承 View 时,如果不在 onDraw() 方法中处理 padding,那么该属性是无法起作用的。另外直接继承 ViewGroup,也需要在onMeasure() 和 onLayout() 中考虑 padding 和子元素的 margin 的影响,否则会导致这两者失效。
  3. 尽量不要在 View 中使用 Handler,View 内部本身提供了 post 系列方法,除非有明确的需要
  4. View 中如果有线程或者动画,需要及时停止,参考 View#onDetachedFromWindow()。当包含此 View 的 Activity 退出或者当前 View 被 remove 的时候,View 的 onDetachedFromWindow() 方法会被调用,与此对应的就是 onAttachedToWindow(),当包含此 View 的 Activity 启动时,View 的 onAttachedToWindow() 会被调用。另外,当 View 变得不可见时,也需要及时停止线程和动画,否则可能造成内存泄漏。
  5. View 带有滑动嵌套情形时,需要处理好滑动冲突
2.3 大致的实现内容
2.3.1 根据实际需要,定义自定义属性

(1)在 res/values 目录下创建自定义属性的 xml,比如 attrs.xml,也可以根据实际需要命名。

<resources>
	<declare-styleable name="CustomView">
		<attr name="attr_name" format="format style" />
	</declare-styleable>
</resources>

(2)在 View 的构造方法中解析自定义属性并处理。

public CustomView(Context context, AttributeSet attrs, int defStyleAttr) {
	super(context, attrs, defStyleAttr);
	// 得到自定义属性对应的 TypedArray 对象
	TypedArray a = context.obtainStyledAttributes(attrs, R.styleable. CustomView);
	xxx = a.getXXX(R.styleable. CustomView_attr_name, defaultValue);
	// 将资源进行回收
	a.recycle()
}

(3)在布局文件中使用自定义属性,使用的时候,要先定义命名空间,即 schemas 声明:

xmlns:schemas_name="http://schemas.android.com/apk/res-auto"

// 或者
xmlns:schemas_name="http://schemas.android.com/apk/res/应用的包名"
2.3.2 onMeasure() 方法

单一 View,一般重写此方法,针对 wrap_content 情况,规定 View 默认的大小值,避免与 match_parent 情况一致(如果不重写,对于 wrap_content 的处理会与 match_parent 一致 )。

而处理 wrap_content 情况,更准确的说,是处理 SpecMode 为 AT_MOST 的情况,此时需要设置默认的大小,或者根据控件自身的内容,以及 padding 来设置一个对应的值。

而对于 ViewGroup,若不重写,就会执行和父类 View#onMeasure() 相同逻辑,导致无法测量子 View。因此一般会重写 onMeasure() 方法,根据布局控件的实际要求遍历测量所有子 View 并调用其 meaure() 方法。(如 FrameLayout)。

2.3.3 onLayout() 方法

单一 View,不需要实现该方法。ViewGroup 必须实现,该方法是个抽象方法,实现该方法,来对子 View 进行布局。

2.3.4 onDraw() 方法

一般单一的 View 需要实现该方法,绘制实际内容,ViewGroup 则视情况而定。


3.有关 MeasureSpec

在调用 onMeasure(int widthMeasureSpec, int heightMeasureSpec) 的时候,会传递两个参数,分别是 width 和 height 的 MeasureSpec。

MeasureSpec 是一个 32 位的 int 值,高 2 位为 SpecMode(测量模式),低 30 位为 SpecSize(在某种测量模式下的规格大小)。

private static final int MODE_SHIFT = 30;
private static final int MODE_MASK  = 0x3 << MODE_SHIFT;

public static final int UNSPECIFIED = 0 << MODE_SHIFT;
public static final int EXACTLY     = 1 << MODE_SHIFT;
public static final int AT_MOST     = 2 << MODE_SHIFT;

public static int getMode(int measureSpec) {
    //noinspection ResourceType
    return (measureSpec & MODE_MASK);
}

public static int getSize(int measureSpec) {
    return (measureSpec & ~MODE_MASK);
}

public static int makeMeasureSpec(@IntRange(from = 0, to = (1 << MeasureSpec.MODE_SHIFT) - 1) int size,
                                  @MeasureSpecMode int mode) {
    if (sUseBrokenMakeMeasureSpec) {
        return size + mode;
    } else {
        return (size & ~MODE_MASK) | (mode & MODE_MASK);
    }
}

3.1 SpecMode 的类别

(1)UNSPECIFIED,父容器不对 View 有任何限制,要多大给多大,该状态一般用于系统内部,表示一种测量状态;

(2)EXACTLY,父容器已经监测出 View 所需要的精确大小,此时 View 的最终大小即为 SpecSize 所指定的值。其对应于 LayoutParams 中的 match_parent 和具体的数值这两种模式;

(3)AT_MOST,父容器指定了一个可用大小的 SpecSize,View 最大不能大于该值,具体是什么值看 View 的具体实现。其对应于 LayoutParams 中的 wrap_content。

3.2 View 的 MeasureSpec 的确定

分为两种情况:

(1)对于顶级 View(即 DecorView),其 MeasureSpec 由 窗口的尺寸 和其自身的 LayoutParams 共同决定。

// rootDimension 即 DecorView 的 LayoutParams 中设置的 width/height
private static int getRootMeasureSpec(int windowSize, int rootDimension) {
    int measureSpec;
    switch (rootDimension) {
    // 精确模式,大小即窗口大小
    case ViewGroup.LayoutParams.MATCH_PARENT:
        // Window can't resize. Force root view to be windowSize.
        measureSpec = MeasureSpec.makeMeasureSpec(windowSize, MeasureSpec.EXACTLY);
        break;
    // 最大模式,大小不定,但是不能超过窗口的大小
    case ViewGroup.LayoutParams.WRAP_CONTENT:
        // Window can resize. Set max size for root view.
        measureSpec = MeasureSpec.makeMeasureSpec(windowSize, MeasureSpec.AT_MOST);
        break;
    // 固定大小,精确模式,大小即 LayoutParams 中指定的大小
    default:
        // Window wants to be an exact size. Force root view to be that size.
        measureSpec = MeasureSpec.makeMeasureSpec(rootDimension, MeasureSpec.EXACTLY);
        break;
    }
    return measureSpec;
}

(2)对于普通的 View,其 MeasureSpec 由父容器的 MeasureSpec 和自身的 LayoutParams 共同决定,此外还受 View 的 margin 及 padding 有关。可以参阅

// spec 为 parent 的 widthMeasureSpec 或者 heightMeasureSpec
// padding 为父容器设置的 padding,PaddingLeft+PaddingRight 或者 PaddingTop+PaddingBottom
// childDimension 即子 View 的 LayoutParams 设置的 width 或者 height
// 静态方法
ViewGroup.getChildMeasureSpec(int spec, int padding, int childDimension) 

该方法对应的处理逻辑如下表,其中 parentSize 指父容器中目前可使用的大小,即父容器的 specSize - padding 的值(在代码中为 Math.max(0, specSize - padding))。
在这里插入图片描述


4. 补充内容

(1)View 的测量宽高和最终宽高有什么区别?

该问题可以具体为 View 的 getMeasureWidth() 和 getWidth() 这两个方法的区别(关于 height 本质上一样)。

public final int getWidth() {
    return mRight - mLeft;
}

public final int getHeight() {
    return mBottom - mTop;
}

public final int getMeasuredWidth() {
	// mMeasuredWidth 本身是包含 SpecMode 的
    return mMeasuredWidth & MEASURED_SIZE_MASK;
}

public final int getMeasuredHeight() {
	// mMeasuredHeight 本身是包含 SpecMode 的
    return mMeasuredHeight & MEASURED_SIZE_MASK;
}

在 View 的实现中,View 的测量宽高与最终宽高是相等的。只不过测量宽高形成于 measure 过程,而最终宽高形成于 View 的 layout 过程,即两者的赋值时机不同。

但是也不是绝对的,比如重写 View 的 layout() 方法:

public void layout(int l, int t, int r, int b) {
	super.layout(l, t, r + 100, b + 100);
}

上述情况就会导致 View 的最终宽高比测量宽高大 100px。

还有一种情况就是某些情况下,View 需要 measure 多次才能确定自己的测量宽高,在前几次可能不一致,但是正常情况下,最终的测量宽高和最终宽高是相同的。

(2)正确获取 View 的宽高的途径

在 Activity 的 onCreate、onStart、onResume 的首次执行中均无法正确得到某个 View 的宽高信息,这是因为这几个生命周期方法执行时,无法保证 View 测量完毕。

可以通过一下几种方法解决:

1、Activity/View#onWindowFocusChanged()

该方法调用时,View 已经初始化完毕了。但是该方法会被调用多次,在 Activity onResume() 和 onPause() 的时候均就被调用。

2、View#post(Runnable)

执行该 runnable 的时候,View 已经初始化好了。

3、使用 ViewTreeObserver

@Override
@Override
protected void onStart() {
    super.onStart();
    view.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
        @Override
        public void onGlobalLayout() {
        	// 移除该 OnGlobalLayoutListener
            view.getViewTreeObserver().removeOnGlobalLayoutListener(this);
            int width = view.getMeasuredWidth();
            int height = view.getMeasuredHeight();
        }
    });
}

伴随 View 树的状态改变,onGlobalLayout() 会被调用多次,因此需要在适当的时机移除该监听。

View相关问题解惑(ViewRootImpl,PhoneWindow创建时机,View.post为何可以获取View宽高) 毕业一年了,都没有找到时间对Android技术进行整理,疲于项目工作,发现对一些基础性的疑惑没有进行追根溯源。若想在技术方面有所提升,对源码的解读是必须要迈过去的坎。以后要继续坚持写博客了。 1. Activity.setContentView()到底做了什么?执行了此方法,就开始渲染视图(执行ViewRootImpl.performTransversal)了吗? 首先回答:setConten... 阅读详情

相关推荐

JavaWeb笔记整理+图解——Filter过滤器

JavaWeb笔记整理+图解——Filter过滤器

i_Water_boy的博客 2477

view计算机术语,计算机前三章知识点汇总.docx

第一章 计算机基础知识1、计算机的特点: HYPERLINK "/TG/view/id-???" 自动地运行程序、运算速度快、运算精度高、具有记忆和逻辑判定能力、可靠性高,还具有体积小、重量轻、耗电少、维护方便、易 HYPERLINK "/TG/view/id-????" 操作、 HYPERLINK "/TG/view/id-????" 功能强、 HYPERLINK "/TG/view/id-??...

weixin_34759094的博客 418

金桔智慧物流之容器(托盘、周转箱等)定位及周转方案原理

金桔智慧物流之容器(托盘、周转箱等)定位及周转方案原理 在物流行业种,托盘是标准化运输的关键的配件,而容器存在丢失、盘点、闲置等管理问题。如何通过信息化的手段提升容器的寿命,提高调配效率,降低闲置是物流容器行业的关键点。 金桔蓝牙网关配合金桔蓝牙资产管理终端可以解决物流行业痛点问题。 容器管理面临的问题: 技术方案 场景描述之库房 场景描述之车辆 场景描述之终端 方案优势 ...

jinjufocus的博客 1180

View的工作原理

这篇文章主要整理一下Android系统中,View的工作流程。主要就是measure、layout、draw三个过程。 我们知道,在ActivityThread中,当Activity对象被创建完毕后,会将DecorView添加到Window中,同时会创建ViewRootImpl对象,并将ViewRootImpl对象和DecorView建立联系。View的绘制流程从ViewRootImpl的per...

weixin_44380128的博客 217

AI学习记录 - transformer的位置编码的理解

先看三角函数为什么可以,我们看下三角函数的图像先提一个点:位置信息肯定是唯一的,或者是在很长的文字当中,起码重复度不会太高,x轴代表位置,y轴代表叠加上去的值1、假设只使用一个三角函数sin,我们将第2和第14两个位置输入到sin,他们的值很像,在神经网络的训练中,很容易把第2个位置和第14个位置当成是一个位置,不满足我们上面说到的要求位置唯一性。sin2sin14。

weixin_43954090的博客 1412

CAN通信:EB中配置CAN驱动,配置参数解析

以S32K314芯片说明,其他芯片不同,参数配置也有差异。

zhangxiaio1的博客 2166

Android的Surface、View、SurfaceView、Window概念整理

转载自:http://www.360doc.com/content/19/0927/10/8335678_863480139.shtml 最近了解了一下Android中几个关于视图的概念:Surface、View、SurfaceView与Window,在此进行一下总结整理 BufferQueue 在此之前,我们先介绍一下BufferQueue。 BufferQueue类是 Android 中所有图形处理操作的核心。它的作用很简单:将生成图形数据缓冲区的一方(生产方)连接到接受数据以进行显示或进一步处理

G的博客 3367

logisim计组实验八 乘法器

原理:点这里 有问题欢迎留言哦~ 文章目录五位阵列乘法器电路图时间延迟分析六位补码阵列乘法器五位无符号乘法流水线原理图电路图原码一位乘法器原理图电路图补码一位乘法器 五位阵列乘法器 电路图 此处注意:全加器FA的cout端是进位端而非输出端 使用硬件控制比循环累加的速度快得多。 但是存在串行进位链 改进版: 时间延迟分析 T是计算相加数的一级门延迟 3n–>2n 性能差别在1.5倍 ...

treblez's blog 2万+

NumPy的实用函数整理之sliding_window_view

numpy高级滑窗方法

学习爱好者fz的博客 6385

使用网分对晶体ESR/L1/C1/C0进行测量计算

Use R&amp;S Vector Network Analyzer test XTAL ESR/L1/C1/C0 測量方法:使用儀器的Port1端口,測量XTAL的S11,通過諧振的參數計算出ESR/L1/C1/C0的值。 實際晶體的等效模型:通常方便晶體分析,使用下圖(b)的等效模型,但實際測量發現晶體存在多個串聯諧振點,實際等效模型更接近(c)。 儀器測量到的S11,其中M...

qq_39138630的博客 2081

双内核架构 Xenomai 4 安装教程

双内核 Xenomai 4 安装指南

^_^ 4464

整理SpringMVC工作原理

SpringMVC工作原理 SpringMVC工作流程 1.用户发送请求到前端控制器 2.前端控制器收到请求后调用处理映射器 3.处理映射器会找到具体的处理器(通过xml配置、注解进行查找),生成处理器对象和拦截器返回前端控制器 4.前端控制器调用处理适配器 5.处理适配器会根据处理器的类型一一匹配,找到后便执行处理器 6.处理器进行具体的业务处理后返回给适配器一个modelandview 7....

java小白 151

FFT中的精度博弈:定点数缩放、块浮点与溢出处理在Vivado IP核中的实践权衡

本文探讨了在Vivado FFT IP核中实现高精度快速傅里叶变换的关键技术,包括定点数缩放策略、块浮点模式及溢出处理机制。通过分析不同精度控制方案的资源开销与性能权衡,为工程师在医疗成像、雷达信号处理等高动态范围应用中优化FFT实现提供实践指导。

melon的博客 1095

view-View基础重认识

View基础重认识前言View的构造方法View的位置参数View的相关方法View与Activity的生命周期进入Activity点击Home键回到桌面重新进入App退出Activity 前言 android中的View形形色色,我们刚开始接触Android的时候就开始于它打交道了,但View以及与View相关的周边的知识点也是非常的繁多,并且从初级到高级我们都有很多可以学习的地方。我所知道的讲...

oheg2010的博客 606

RK3588部署YOLO模型 包含模型量化+npu轻量化+ubuntu+RGA图像加速和多线程模型加速 包源码

本专栏为深度学习部署全栈学习体系,包含68篇由浅入深的教程,专为零基础学习者设计。内容涵盖TensorRT与RK3588平台部署技术,包含Jetson系列和RK系列硬件部署实战,采用"理论+源码+实战"三位一体的教学模式。学习路径从基础环境搭建到模型优化、容器化部署、多硬件平台适配,最终掌握工业级AI部署能力。特色包括C++基础教学、Docker容器化、INT8量化、多线程优化等核心技术,并附带YOLOv5、人脸检测、车牌识别等多个实战项目源码。适合算法工程师转部署方向、嵌入式开发者及对

FJN110的博客 3729

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

android surface windows,Android的Surface、View、SurfaceView、Window概念整理

最近了解了一下Android中几个关于视图的概念:Surface、View、SurfaceView与Window,在此进行一下总结整理BufferQueue在此之前,我们先介绍一下BufferQueue。BufferQueue类是 Android 中所有图形处理操作的核心。它的作用很简单:将生成图形数据缓冲区的一方(生产方)连接到接受数据以进行显示或进一步处理的一方(消耗方)。几乎所有在系统中移动...

weixin_33239386的博客 745

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

SpringMVC 工作原理详解

本文整理自网络,原文出处暂不知,对原文做了较大的改动,在此说明! 先来看一下什么是 MVC 模式 MVC 是一种设计模式. MVC 的原理图如下: SpringMVC 简单介绍 SpringMVC 框架是以请求为驱动,围绕 Servlet 设计,将请求发给控制器,然后通过模型对象,分派器来展示请求结果视图。其中核心类是 DispatcherServlet,它是一个 Servlet,顶层是实现...

Java Punk 2315

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

从入门到精通的Android进阶学习笔记整理,灵魂拷问

前言 随着移动网络的不断升级,客户端的网络传输由3G进化到Wifi、4G、5G,且Wifi场景越来越多。虽然网络环境在变好,但也对网络的应用提出了更高的要求,会发现很多大厂都十分重视网络指标,如果技术人员不加以控制,在弱网、体验、包括服务器带宽、流浪方面都会造成不同程度的损失。 一、关于Handler面试那些问题 1、Handler Looper Message 关系是什么? 2、Messagequeue 的数据结构是什么?为什么要用这个数 据结构? 3、如何在子线程中创建 Handler? 4、Handl

m0_56051002的博客 106

android xwindow 区别,Android的Surface、View、SurfaceView、Window概念整理

最近了解了一下Android中几个关于视图的概念:Surface、View、SurfaceView与Window,在此进行一下总结整理BufferQueue在此之前,我们先介绍一下BufferQueue。BufferQueue类是 Android 中所有图形处理操作的核心。它的作用很简单:将生成图形数据缓冲区的一方(生产方)连接到接受数据以进行显示或进一步处理的一方(消耗方)。几乎所有在系统中移动...

weixin_39820136的博客 432

Android框架的整理之MVC、MVP、MVVM工作原理

前段时间一直忙着开发没时间做些资料的整理,现在抽空做下资料整合 一、MVC简介 MVC是Model-View-Controler的简称

Dota_wy的博客 652

View系列:LayoutInflater

最后为了帮助大家深刻理解Android相关知识点的原理以及面试相关知识,这里放上相关的我搜集整理的24套腾讯、字节跳动、阿里、百度2019-2021面试真题解析,我把技术点整理成了视频和PDF(实际上比预期多花了不少精力),包知识脉络 + 诸多细节。还有高级架构技术进阶脑图、Android开发面试专题资料帮助大家学习提升进阶,也节省大家在网上搜索资料的时间来学习,也可以分享给身边好友一起学习。

bfhye16552的博客 305

自定义View知识体系

自定义View简介在Android原生控件无法满足需求的情况下,但是又需要实现一些特殊效果的时候该怎么办呢?这个时候就可以通过自定义View去实现。因此自定义View是对于Android工程师来说无疑是比较重要的技能。今天我会针对自定义View的一些知识作讲解,水平有限,不对的地方望批评交流。自定义View分类自定义View本质上其实就是通过Java的继承特性去扩展特定需求,且大家都知道Androi

李锦锋 1万+

view.post是如何保证获取到view的真实宽高的

讲解前,首先看一个handler使用的例子 Handler handler1 = new Handler() { @Override public void handleMessage(Message msg) { Log.d("handler", "handler 1 execute"); try { Thread.sleep(2000); ...

libinbin147256369的博客 719

关于 MeasureSpec,view中measure 的整理

1  MeasureSpec的实现。 1.1  measure是如何实现测量控件的宽高和控件的mode。 为了方便分析,我把它全部的源码,都拷出来: public static class MeasureSpec { private static final int MODE_SHIFT = 30; private static final int MOD

asking1233的专栏 1076

android笔记整理

1.2

每天进步一点点 758

Handler-post和View-post的区别,2024疫情期间八家大厂的Android面试经历和真题整理

今天关于面试的分享就到这里,还是那句话,有些东西你不仅要懂,而且要能够很好地表达出来,能够让面试官认可你的理解,例如Handler机制,这个是面试必问之题。有些晦涩的点,或许它只活在面试当中,实际工作当中你压根不会用到它,但是你要知道它是什么东西。最后在这里小编分享一份自己收录整理上述技术体系图相关的几十套腾讯、头条、阿里、美团等公司20年的面试题,把技术点整理成了视频和PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节,由于篇幅有限,这里以图片的形式给大家展示一部分。还有。

2301_79655511的博客 491
上一篇: 点击事件分发机制 关键源码笔记
下一篇: 简单工厂、工厂方法、抽象工厂、Builder 模式 笔记整理
OneDeveloper
博客等级 码龄9年 61粉丝 161原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值