Android View的生命周期详解

Kotlin Android Extensions插件弃用后,如何优雅迁移View Binding解决控件爆红问题 本文针对Kotlin Android Extensions插件弃用后出现的控件爆红问题,提供了向View Binding的完整迁移指南。详细阐述了View Binding在空安全、类型安全和性能上的优势,并逐步演示了在Activity、Fragment、Adapter等场景中的具体替换方法,帮助开发者优雅解决kotlinx.android.synthetic依赖问题,提升代码质量。 阅读详情

View生命周期相关方法:

  1. onFinishInflate() 当View中所有的子控件均被映射成xml后触发
  2. onMeasure( int , int ) 确定所有子元素的大小
  3. onLayout( boolean , int , int , int , int ) 当View分配所有的子元素的大小和位置时触发
  4. onSizeChanged( int , int , int , int ) 当view的大小发生变化时触发
  5. onDraw(Canvas) view渲染内容的细节
  6. onKeyDown( int , KeyEvent) 有按键按下后触发
  7. onKeyUp( int , KeyEvent) 有按键按下后弹起时触发
  8. onTrackballEvent(MotionEvent) 轨迹球事件
  9. onTouchEvent(MotionEvent) 触屏事件
  10. onFocusChanged( boolean , int , Rect) 当View获取或失去焦点时触发
  11. onWindowFocusChanged( boolean ) 当窗口包含的view获取或失去焦点时触发
  12. onAttachedToWindow() 当view被附着到一个窗口时触发
  13. onDetachedFromWindow() 当view离开附着的窗口时触发,Android123提示该方法和onAttachedToWindow() 是相反在这里插入代码片的。
  14. onWindowVisibilityChanged( int ) 当窗口中包含的可见的view发生变化时触发

综上所述:View 的关键生命周期为 [改变可见性] --> 构造View --> onFinishInflate --> onAttachedToWindow --> onMeasure --> onSizeChanged --> onLayout --> onDraw --> onDetackedFromWindow

首先来看三分 创建view 的 日志信息 (自定义View 配置到xml文件中):

android:visibility=gone

03-25 19:56:55.934: D/yyyyy(11493): onVisibilityChanged--------=====
03-25 19:56:55.934: D/yyyyy(11493): construct 2 parameters .
03-25 19:56:55.934: E/yyyyy(11493): onFinishInflate
03-25 19:56:55.934: D/yyyyy(11493): onVisibilityChanged--------=====
03-25 19:56:55.934: D/yyyyy(11493): onVisibilityChanged--------=====
03-25 19:56:55.944: D/yyyyy(11493): onRtlPropertiesChanged--------=====
03-25 19:56:55.954: D/yyyyy(11493): onRtlPropertiesChanged--------=====
03-25 19:56:55.954: E/yyyyy(11493): onAttachedToWindow
03-25 19:56:55.954: D/yyyyy(11493): onWindowVisibilityChanged--------=====
03-25 19:56:55.974: D/yyyyy(11493): onWindowFocusChanged--------=====

android:visibility=invisible

03-25 19:57:38.204: D/yyyyy(11694): onVisibilityChanged--------=====
03-25 19:57:38.204: D/yyyyy(11694): construct 2 parameters .
03-25 19:57:38.204: E/yyyyy(11694): onFinishInflate
03-25 19:57:38.204: D/yyyyy(11694): onVisibilityChanged--------=====
03-25 19:57:38.204: D/yyyyy(11694): onVisibilityChanged--------=====
03-25 19:57:38.224: D/yyyyy(11694): onRtlPropertiesChanged--------=====
03-25 19:57:38.224: D/yyyyy(11694): onRtlPropertiesChanged--------=====
03-25 19:57:38.224: E/yyyyy(11694): onAttachedToWindow
03-25 19:57:38.224: D/yyyyy(11694): onWindowVisibilityChanged--------=====
03-25 19:57:38.224: D/yyyyy(11694): onMeasure , width : 1080  ; height: 1557
03-25 19:57:38.224: D/yyyyy(11694): onMeasure , width : 144  ; height: 1500
03-25 19:57:38.234: D/yyyyy(11694): onSizeChanged
03-25 19:57:38.234: I/yyyyy(11694): onLayout --> l: 0  ; r : 144  ; t: 57  ; b: 201  : changed :true
03-25 19:57:38.254: D/yyyyy(11694): onMeasure , width : 1080  ; height: 1557
03-25 19:57:38.254: D/yyyyy(11694): onMeasure , width : 144  ; height: 1500
03-25 19:57:38.254: I/yyyyy(11694): onLayout --> l: 0  ; r : 144  ; t: 57  ; b: 201  : changed :false
03-25 19:57:38.264: D/yyyyy(11694): onWindowFocusChanged--------=====

android:visibility=visible

03-25 19:55:15.434: D/yyyyy(11304): construct 2 parameters .
03-25 19:55:15.434: E/yyyyy(11304): onFinishInflate
03-25 19:55:15.434: D/yyyyy(11304): onVisibilityChanged--------=====
03-25 19:55:15.434: D/yyyyy(11304): onVisibilityChanged--------=====
03-25 19:55:15.454: D/yyyyy(11304): onRtlPropertiesChanged--------=====
03-25 19:55:15.454: D/yyyyy(11304): onRtlPropertiesChanged--------=====
03-25 19:55:15.454: E/yyyyy(11304): onAttachedToWindow
03-25 19:55:15.454: D/yyyyy(11304): onWindowVisibilityChanged--------=====
03-25 19:55:15.454: D/yyyyy(11304): onMeasure , width : 1080  ; height: 1557
03-25 19:55:15.454: D/yyyyy(11304): onMeasure , width : 144  ; height: 1500
03-25 19:55:15.464: D/yyyyy(11304): onSizeChanged
03-25 19:55:15.464: I/yyyyy(11304): onLayout --> l: 0  ; r : 144  ; t: 57  ; b: 201  : changed :true
03-25 19:55:15.474: D/yyyyy(11304): onMeasure , width : 1080  ; height: 1557
03-25 19:55:15.474: D/yyyyy(11304): onMeasure , width : 144  ; height: 1500
03-25 19:55:15.474: I/yyyyy(11304): onLayout --> l: 0  ; r : 144  ; t: 57  ; b: 201  : changed :false
03-25 19:55:15.474: D/yyyyy(11304): onDraw--------=====
03-25 19:55:15.484: D/yyyyy(11304): onWindowFocusChanged--------=====

1、从中不难看到view 默认为可见的 , 不是默认值时先调用 onVisibilityChanged , 但是此时该view 的任何位置信息都不知道。

2、可见性改变后才是调用带有两个参数的构造函数

3、从xml 文件中 inflate 完成

4、将view 加到 window 中 ( View 是gone 的 ,那么View创建生命周期也就结束 )

5、测量view的长宽 ( onMeasure )

6、定位View 在父View中的位置 ( onLayout )–>(View 是invisible , View 创建生命周期结束)

7、onDraw ( 只有可见的 View 才在 window 中绘制 )

在代码中构造View:

setContentView(new CusView(this))输入日志信息如下:

03-25 20:37:51.284: E/yyyyy(12530): construct 1 parameter
03-25 20:37:51.294: D/yyyyy(12530): onVisibilityChanged--------=====
03-25 20:37:51.314: D/yyyyy(12530): onVisibilityChanged--------=====
03-25 20:37:51.314: D/yyyyy(12530): onRtlPropertiesChanged--------=====
03-25 20:37:51.314: D/yyyyy(12530): onRtlPropertiesChanged--------=====
03-25 20:37:51.314: E/yyyyy(12530): onAttachedToWindow
03-25 20:37:51.314: D/yyyyy(12530): onWindowVisibilityChanged--------=====
03-25 20:37:51.314: D/yyyyy(12530): onMeasure , width : 1080  ; height: 1557
03-25 20:37:51.314: D/yyyyy(12530): onSizeChanged
03-25 20:37:51.324: I/yyyyy(12530): onLayout --> l: 0  ; r : 1080  ; t: 0  ; b: 1557  : changed :true
03-25 20:37:51.324: D/yyyyy(12530): onMeasure , width : 1080  ; height: 1557
03-25 20:37:51.324: I/yyyyy(12530): onLayout --> l: 0  ; r : 1080  ; t: 0  ; b: 1557  : changed :false
03-25 20:37:51.324: D/yyyyy(12530): onDraw--------=====
03-25 20:37:51.344: D/yyyyy(12530): onWindowFocusChanged--------=====

从测试结果来看,默认情况下view的长和宽默认和父 view 的长和宽一致 。

虽然调用了onDraw 函数,但是在屏幕上却看不到任何内容,什么原因?
当看不到任何内容时,请先检查 View要绘制的内容是否制定。

为什么我指定了LayoutParameters,却没有效果?

在不恰当的生命周期中指定LayoutParameters,会被忽略掉,比如如下代码:

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // setContentView(R.layout.activity_main);
        view = new CusView(this);
        view.setImageResource(R.drawable.ic_launcher);
        FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(70, 70);
        view.setLayoutParams(params);
        setContentView(view);
    }

正确的方法应该是放到 onWindowFocusChanged 方法获取到焦点后再指定LayoutParameters,如下代码:

@Override
    public void onWindowFocusChanged(boolean hasFocus) {
        // TODO Auto-generated method stub
        super.onWindowFocusChanged(hasFocus);
        if (hasFocus) {
            view.setImageResource(R.drawable.ic_launcher);
            FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(70, 70);
            view.setLayoutParams(params);
        }
    }

为什么我指定LayoutParameters参数时报异常?异常信息如下:

java.lang.ClassCastException: android.view.ViewGroup$LayoutParams cannot be cast to android.view.ViewGroup$MarginLayoutParams
java.lang.Object
? 	android.view.ViewGroup.LayoutParams
  	? 	android.view.ViewGroup.MarginLayoutParams

LayoutParameters的参数类型不对,从上面继承关系可以看到MarginLayoutParameters扩展了ViewGroup的layoutParameters ,将其修改为任意支持margin动作的LayoutParameters 。

接下来我们看三份销毁 View 的日志:

android:visibility=visible

03-25 21:15:35.404: D/yyyyy(14589): onWindowFocusChanged--------=====
03-25 21:15:35.484: D/yyyyy(14589): onWindowVisibilityChanged--------=====
03-25 21:15:35.504: D/yyyyy(14589): onDetachedFromWindow--------=====

android:visibility=gone

03-25 21:16:09.964: D/yyyyy(14736): onWindowFocusChanged--------=====
03-25 21:16:10.054: D/yyyyy(14736): onWindowVisibilityChanged--------=====
03-25 21:16:10.064: D/yyyyy(14736): onDetachedFromWindow--------=====

android:visibility=invisible

03-25 21:16:42.534: D/yyyyy(14860): onWindowFocusChanged--------=====
03-25 21:16:42.594: D/yyyyy(14860): onWindowVisibilityChanged--------=====
03-25 21:16:42.614: D/yyyyy(14860): onDetachedFromWindow--------=====

从以上内容可以看到,visibility属性对view的销毁流程没有影响。

综上所述:View 的关键生命周期为 [改变可见性] --> 构造View --> onFinishInflate --> onAttachedToWindow --> onMeasure --> onSizeChanged --> onLayout --> onDraw --> onDetackedFromWindow

最后给出一小段代码用于在屏幕上拖动view(通过修改view的 layout ):

private float mDownX, mDownY, x, y;
    private int dx, dy, il, ir, it, ib;
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        x = event.getX();
        y = event.getY();
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                mDownX = event.getX();
                mDownY = event.getY();
                il = getLeft();
                ir = getRight();
                it = getTop();
                ib = getBottom();
                break;
            case MotionEvent.ACTION_MOVE:
            case MotionEvent.ACTION_UP:
                dx += Math.round(x - mDownX);
                dy += Math.round(y - mDownY);
                layout(il + dx, it + dy, ir + dx, ib + dy);
                break;
        }
        return true;
    }

Compose与Android View的混合开发实战指南 本文详细介绍了Compose与Android View混合开发的实战指南,包括基础互操作性、复杂场景下的布局实践以及性能优化技巧。通过实际案例和代码示例,帮助开发者高效实现两种UI体系的共存与协作,提升应用开发效率。 阅读详情

相关推荐

深入理解Android View的“生命周期”:从诞生到绘制的完整旅程

Android View的生命周期包含14个关键回调方法:1)onFinishInflate()完成XML映射;2)onMeasure()确定子控件尺寸;3)onLayout()布局子控件位置;4)onSizeChanged()处理尺寸变化;5)onDraw()执行绘制。还包括6-9)按键和触摸事件处理;10-11)焦点变化回调;12-13)窗口附着/分离;14)窗口可见性变化。这些方法完整描述了View从创建、布局、交互到销毁的全过程,是Android UI开发的核心机制。

学无止境 737

Android View的生命周期

View是什么? 官方源码注释中的定义:这个类是用户接口的基础构件。View表示屏幕上的一块矩形区域,负责绘制这个区域和事件处理。 View是所有widget类的基类,Widget类用于创建交互式UI构件(按钮,输入框等)。 View类的ViewGroup子类是layout的基类,Layout是一个不可见的容器,它保存着 View(或ViewGroup)并定义这些View的layout 属

LiBo 795

安卓面试资料总结

本文主要包含三部分内容:个人面试准备、工作经验技术问题和纯技术问题。第一部分详细列出了面试常见问题及参考答案,包括自我介绍、项目经验、离职原因等;第二部分聚焦Android开发技术,涵盖开机流程、系统服务创建、按键上报等具体实现;第三部分解析Activity生命周期、Service启动方式等技术要点。全文内容实用性强,既包含面试技巧指导,又提供具体技术实现方案,适合Android开发者参考学习。

weixin_44081096的博客 417

android View生命周期

android 甲骨文之 View 生命周期 前言: 最近在写materialDesign系列的博客,上一篇介绍了NestedScrollView的源码分析,本来计划本篇为CoordinatorLayout源码分析,但是CoordinatorLayout涉及到了View的生命周期的知识,我又不想潦草的糊弄,所以那就穿插一篇View的生命周期吧 源码基于: android-30 整体流程 先来看看整体流程,然后再深入源码! 第一次加载: szj_TestActivity: activity onCrea

高级开发者进阶ing... QaQ 4253

Android开发 自定义底部可滑动浮层Listview.apk

根据Android开发 View的生命周期结合代码详解和一张流程图带你完全搞懂Android的View事件分发机制并结合源码详解,实现列表底部悬浮自动弹起手动滑动皆可实现,平滑滚动效果极佳。

Win11桌面图标小箭头去除与恢复:解决任务栏关联错误的完整指南

本文提供了一份完整的Win11桌面图标小箭头去除与恢复指南,重点解决了因错误方法导致的任务栏关联错误问题。通过分析注册表中IsShortcut键值与Shell Icons的原理,推荐安全的“替换图标资源法”,并提供了可一键执行的批处理脚本,确保在美化桌面的同时不影响系统功能与默认应用设置。

weixin_29288313的博客 941

android view的生命周期

android view有以下14个周期: 1、onFinishInflate() 当View中所有的子控件均被映射成xml后触发 。 2、onMeasure( int , int ) 确定所有子元素的大小 。 3、onLayout( boolean , int , int , int , int ) 当View分配所有的子元素的大小和位置时触发 。 4、onSizeChanged( in

学无止境~ 733

别再死磕U-Net了!用PyTorch手把手教你搭建ResUnet,搞定医学图像分割(附完整代码)

本文详细介绍了如何利用PyTorch搭建ResUnet模型,通过引入残差连接解决医学图像分割中的梯度消失、特征退化和细节丢失问题。与传统U-Net相比,ResUnet在Dice系数和收敛速度上均有显著提升,特别适合处理脑部MRI等复杂医学图像。文章还提供了完整的代码实现和关键训练技巧,帮助开发者快速掌握这一先进技术。

weixin_42552637的博客 326

Android View 生命周期详解

当用户触摸屏幕时,触摸事件会从顶层的View开始向下传递,经过一系列的View或ViewGroup,最终到达目标View。和。触摸事件从顶层的View开始,调用方法进行事件分发。如果是ViewGroup,会先调用方法判断是否拦截事件。如果拦截,则事件由该ViewGroup处理;如果不拦截,则继续向下传递给子视图。子视图调用方法,重复上述步骤,直到找到目标View。目标View调用方法处理事件,如果处理成功则返回true,表示事件已处理;如果处理失败则返回false,事件会向上传递给父视图处理。

Android领域开发创作者 1265

8.9华为OD机试真题 新系统 - 灯带颜色变换 (Java/Py/C/C++/Js/Go)

8.9华为OD机试真题 新系统 - 灯带颜色变换 (Java/Py/C/C++/Js/Go)

算法大师! 663

基于STM32的多传感器融合的设施农业小型搬运机器人避障控制系统设计

针对设施农业场景中狭窄通道、障碍物多样(如农机具、作物植株、水管)的特点,设计一款基于 STM32 的小型搬运机器人避障控制系统。系统通过多传感器融合实现 360° 环境感知,采用模糊 PID 控制算法实现平滑避障,满足温室、大棚等场景的搬运需求。通过在温室环境测试,系统可实现对直径≥5cm 障碍物的有效检测(检测距离误差≤5%),避障转向半径≤30cm,平均功耗≤15W。后续可通过增加激光雷达(如 TFmini)提升远距离障碍物检测能力,结合 SLAM 算法实现路径规划。

weixin_42300449的博客 859

Android开发之Activity以及View的生命周期详解

关于activity和View的生命周期,网路上已经有很多详细的解释了。并且有一副很经典的示意图,简单地就能百度到,我这里就不放上去了。这里我针对网路上的有些没有讲到的,或者有些误区,然后结合两者说下。 onCreate(Bundle savedInstanceState)和onFinishInflate() 从字面上都可以看出,onCreate是activity的创建回调,一般我们会把setCon

feiyang877647044的博客 3433

RTOS与Linux功能差异与应用场景全面对比

在嵌入式系统的开发中,操作系统的选择至关重要。和是两种广泛应用的操作系统,它们在功能、设计目标以及应用领域中各具优势。随着嵌入式系统的不断发展,已成为嵌入式行业的大趋势。那么,这两者到底有什么不同呢?

硬核科技 400

Android开发 View的生命周期结合代码详解

咱们以TextView控件为例: /** * Created by SunshineBoy on 2020/9/23. */ public class TestTextView extends android.support.v7.widget.AppCompatTextView { public TestTextView(Context context) { super(context); Log.e("TestTextView","TestTextView

SunshineBoy的博客 2153

企业合规审查系统开发实战:基于知识图谱与深度学习的智能引擎构建(附完整Python代码)

动态合规监测:实时追踪法规变化并更新知识库智能合约审计:区块链智能合约的自动合规检查跨域知识融合:整合财务、法律、业务多维度数据可解释性增强:基于Attention机制生成合规审查依据。

理论都是虚的,代码才是王道。 455

LangGraph实战训练营-从零构建AI驱动的wiki知识库

本文深入解析 LangChain 团队开源的 Deep Agents 框架核心示例——LLM Wiki,一个基于大语言模型自动构建和维护持久化知识库的生产级 AI Agent 系统。文章从项目架构、环境搭建、核心原理到实战操作全面展开:详解 CompositeBackend 组合后端与细粒度权限控制的安全设计、四种工作模式(初始化/摄取/查询/质量检查)的完整流程、LangSmith 远程沙箱的隔离执行机制,以及人机协同审核(HITL)的实践应用。

program哲学 197

android生命周期_Android开发 View的生命周期结合代码详解

咱们以TextView控件为例:/** * Created by SunshineBoy on 2020/9/23. */public class TestTextView extends android.support.v7.widget.AppCompatTextView { public TestTextView(Context context) { super(cont...

weixin_39545017的博客 158

Python爬虫实战:构建药监局药品批准信息本地查询系统

在医药信息化时代,药品批准信息的快速查询对于医药从业者、研究人员和普通消费者都具有重要意义。国家药品监督管理局(NMPA)提供了官方的药品查询系统,但有时我们需要建立本地数据库以便批量分析或离线查询。本文将详细介绍如何使用Python爬虫技术,结合最新的异步爬虫框架和技术栈,构建一个完整的药监局药品信息本地查询系统。本系统将实现以下功能:自动化爬取药监局官网的药品批准信息数据清洗和结构化存储建立本地查询接口数据定期更新机制pythonimport os"""药品类型枚举"""

2201_76125261的博客 726

Android View的onFinishInflate和onSizeChanged生命周期详解

本文从源代码的角度讲述了onSizeChange和onFinishInflate以及layout三个View的生命周期函数的作用和回调时机!

啃黄瓜的蜗牛 1万+

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...

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

Android中Activity、View和Window关系详解

Window、Activity、View都经常用到,但三者关系还是没有系统的理清,今天咱们就开始整理整理这三者的关系:Window:顶级窗口外观和行为策略的抽象基类。唯一实现是 PhoneWindow类。Activity:四大组件之一,它提供一个界面让用户点击和各种滑动操作。View:代表用户界面组件的基本构建块,UI 组件。

allen_xu_2012_new的博客 2327

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

Android自定义View

Android自定义view自定View的概念, 什么是自定义View??为什么学习自定义View??自定义View的重要性自定义View的原则:自定义view的有四种形式:代码实现 自定View的概念, 什么是自定义View?? 在Android系统中,使用系统自带的控件重新组合或者自定义类继承View或者ViewGroup实现特定的效果。 为什么学习自定义View?? 1, 整个View控件在...

CXSDD的博客 368

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

安卓View开发心得(二)

2.善于利用“生命周期” 安卓VIew生命周期是面向对象设计模式中“模板方法模式”的一个经典应用。由系统服务(AMS、WMS等)维护View的生命周期,这些View的生命周期的细节app开发者可以不必了解,只需要知道一些关键的逻辑节点;这些关键的逻辑节点以关键的类似onXXX()方法的方式存在,app开发者只要在自定义的View子类中重写这些方法即可。一个视图(View),从内存中的对象

@甘道夫@的专栏 730

android view销毁事件,Android View生命周期(笔记记录)

一、View 的定义View 就是屏幕上的一块矩形区域,我们可以在这块区域绘制我们想让用户看到的图形(负责绘制这个区域和事件的处理),View 默认是可见的。二、View的生命周期View生命周期的相关方法在了解View的生命周期之前我们先来了解View生命周期的相关方法:1.创建(creation)1)Constructors(构造函数):有一种形式的构造函数是View在代码中被创建时调用(第一...

weixin_29422145的博客 2852
上一篇: Android总结篇系列:Android Service
下一篇: Android:JNI 与 NDK到底是什么?
.NET跨平台
博客等级 码龄15年 6066粉丝 738原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值