setContentView学习(一)

news2024/12/25 9:15:57

setContentView流程分两种情况,一种是继承自Activity的情况,另一种是继承自AppCompatActivity的情况,下面分别介绍。

先说继承自Activity的情况,源码为android-30

public class Activity extends ContextThemeWrapper {

    public void setContentView(@LayoutRes int layoutResID) {
        getWindow().setContentView(layoutResID);
        initWindowDecorActionBar();
    }

其中getWindow()返回的是在Activity中定义的Window对象,而Window是一个抽象类,setContentView又是抽象方法,所以必须找到Window的实现类

/**
 * The only existing implementation of this abstract class is
 * android.view.PhoneWindow, which you should instantiate when needing a
 * Window.
 */
public abstract class Window {

通过Window类的介绍可以看到,Window只有一个实现类:PhoneWindow,另外通过模拟机调试android-30的源码也可以定位到Window的实现类是 PhoneWindow,看下具体实现

public class PhoneWindow extends Window implements MenuBuilder.Callback {

    @Override
    public void setContentView(int layoutResID) {
        if (mContentParent == null) {
            installDecor();
        } else if (!hasFeature(FEATURE_CONTENT_TRANSITIONS)) {
            mContentParent.removeAllViews();
        }

        if (hasFeature(FEATURE_CONTENT_TRANSITIONS)) {
           ...
        } else {
            mLayoutInflater.inflate(layoutResID, mContentParent);
        }
        ...
        mContentParentExplicitlySet = true;
    }

可以看到我们平时写在Activity中的布局被加载到了mContentParent中,那么mContentParent又是哪里创建的,接下来会提到,核心流程主要是看 installDecor()

private void installDecor() {
        mForceDecorInstall = false;
        if (mDecor == null) {
            mDecor = generateDecor(-1);
            mDecor.setDescendantFocusability(ViewGroup.FOCUS_AFTER_DESCENDANTS);
            ......
        } else {
            mDecor.setWindow(this);
        }
        if (mContentParent == null) {
            mContentParent = generateLayout(mDecor);
            ......
        }
}

通过上面的代码可以看到,setContentView的主要核心流程

1. 创建生成顶层View DecorView

2. 以DecorView为父容器,解析并生成xml布局

其中 generateDecor()的流程比较简单,直接new了一个DecorView并返回,下面看geraterLayout()方法的流程,可以看到generateLayout()方法生成的布局就是mContentParent

注意其传参为上面创建的DecorView

protected ViewGroup generateLayout(DecorView decor) {

        TypedArray a = getWindowStyle();
        ......
        int layoutResource;
        int features = getLocalFeatures();
        // System.out.println("Features: 0x" + Integer.toHexString(features));
        if ((features & ((1 << FEATURE_LEFT_ICON) | (1 << FEATURE_RIGHT_ICON))) != 0) {
            ......
        } else if {
            ......
        } else if ((features & (1 << FEATURE_ACTION_MODE_OVERLAY)) != 0) {
            layoutResource = R.layout.screen_simple_overlay_action_mode;
        } else {
            // Embedded, so no decoration is needed.
            layoutResource = R.layout.screen_simple;
        }
        ......
        mDecor.onResourcesLoaded(mLayoutInflater, layoutResource);
        ViewGroup contentParent = (ViewGroup)findViewById(ID_ANDROID_CONTENT);
        ......
        return contentParent;

}

这里会根据不同的feature选择不同的系统xml布局,我们就以最简单的情况为例,也就是最后一种情况,来看下系统布局 screen_simple.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    android:orientation="vertical">
    <ViewStub android:id="@+id/action_mode_bar_stub"
              android:inflatedId="@+id/action_mode_bar"
              android:layout="@layout/action_mode_bar"
              android:layout_width="match_parent"
              android:layout_height="wrap_content"
              android:theme="?attr/actionBarTheme" />
    <FrameLayout
         android:id="@android:id/content"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
         android:foregroundInsidePadding="false"
         android:foregroundGravity="fill_horizontal|top"
         android:foreground="?android:attr/windowContentOverlay" />
</LinearLayout>

会通过DecorView的 onResourcesLoaded()方法加载上面的布局,注意:其中FrameLayout的id

void onResourcesLoaded(LayoutInflater inflater, int layoutResource) {
        ......
        mDecorCaptionView = createDecorCaptionView(inflater);
        final View root = inflater.inflate(layoutResource, null);
        if (mDecorCaptionView != null) {
            ......
        } else {
            // Put it below the color views.
            addView(root, 0, new ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT));
        }
        mContentRoot = (ViewGroup) root;
        initializeElevation();
    }

同样是使用LayoutInflater解析加载布局,最后通过addView()将解析后的布局添加到DecorView

下面通过一个流程图来对以上流程做一个总结

​​​​​​​

 

附图:继承自Activity的布局层级图


​​​​​​​

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/111871.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【综合】简单加解密——寻找序列号

【综合】简单加解密——寻找序列号 下面文字对你可能有用(复制粘贴): #include <stdlib.h> #include <string.h> #include “malloc.h” #define MaxPass 66 // 最多66段密文 #define NumbPwdTable 5 // 密码表的份数 #define SizePwdTable 0x210 // 每份密码表占…

Hulu | 圣诞剧集推荐(2022)

Happy Holidays&#xff01;寒冷的冬日&#xff0c;迎接我们的不仅仅有礼物、欢笑和香气扑鼻的热红酒&#xff0c;还有新上映的节日大片&#x1f3ac;。每每想到节日电影&#xff0c;我们的脑海中总会浮现出真爱至上、小鬼当家这样的经典节日老片&#xff0c;但如果今年的你准备…

前端小知识:赋予变量默认值(逻辑与运算符、空值合并运算符、逻辑空运算符)

8. 逻辑与运算符、空值合并运算符、逻辑空运算符&#xff08;可用赋予默认值&#xff09; &#xff08;空值合并运算符&#xff09;官方文档&#xff1a; https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Nullish_coalescing   &#xff08;逻辑…

搭建VScode在Windows的ubuntu子系统下开发环境

大家一般都是装的windows系统&#xff0c;但是要学习linux C后台开发&#xff0c;又不想装linux&#xff0c;也没有另一台机器。 windows11的应用商城有ubuntu可以安装&#xff0c;因此&#xff0c;我们可以用vscode远程ubuntu进行c的开发 1&#xff0c;安装vscode 微软官网安…

【Pycharm教程】在 PyCharm 中使用 Vim 编辑器 (IdeaVim)

IdeaVim插件在 PyCharm 编辑器中模拟 Vim&#xff0c;包括普通、插入和可视模式、命令行和 Ex 模式、Vim 正则表达式和配置以及其他功能。 安装 IdeaVim 插件 1.在Settings/Preferences对话框 ( CtrlAltS) 中&#xff0c;选择Plugins。 2.在Marketplace中找到IdeaVim插件&…

RabbitMQ 第一天 基础 5 Spring 整合RabbitMQ 5.4 Spring 整合 RabbitMQ【配置详解】

RabbitMQ 【黑马程序员RabbitMQ全套教程&#xff0c;rabbitmq消息中间件到实战】 文章目录RabbitMQ第一天 基础5 Spring 整合RabbitMQ5.4 Spring 整合 RabbitMQ【配置详解】5.4.1 配置详解第一天 基础 5 Spring 整合RabbitMQ 5.4 Spring 整合 RabbitMQ【配置详解】 5.4.1 配…

由SOFARPC示例介绍基本流程和基础源码

由SOFARPC示例介绍基本流程和基础源码 1. Server 先看 Server 端测试方法&#xff1a; public class QuickStartServer {public static void main(String[] args) {ServerConfig serverConfig new ServerConfig().setProtocol("bolt") // 设置一个协议&#xff0…

内容资产管理11问

&#x1f447;点击一键关注主笔&#xff1a;邹小困、邝晴岚主持人&#xff1a;增长黑盒分析师Emma出品&#xff1a;增长黑盒研究组前言在这个信息爆炸的数据时代&#xff0c;各个行业正积极推进数字化转型&#xff0c;产业升级与技术赋能成为主题之一。在推进企业线上线下融合的…

SEO 已死,LLMO 万岁

“北风那个吹&#xff0c;雪花那个飘”&#xff0c;我手捧一杯咖啡&#xff0c;听着白毛女。朋友坐在对面高谈阔论&#xff1a;“有了 ChatGPT&#xff0c;我再也不缺内容了&#xff0c;SEO 的春天就要来了&#xff01;”然而他没有看到真相是 —— ChatGPT 直接颠覆了 SEO 行业…

JVM【垃圾回收相关概念和垃圾回收器】

垃圾回收相关概念 System.gc()的理解 在默认情况下&#xff0c;通过**system.gc&#xff08;&#xff09;**者Runtime.getRuntime().gc() 的调用&#xff0c;会显式触发FullGC&#xff0c;同时对老年代和新生代进行回收&#xff0c;尝试释放被丢弃对象占用的内存。 然而syste…

AutoDL+Xftp+Xshell+VSCode配合使用教程

一、AutoDL AutoDL是一款经过众多算法业内大牛精心调教的云GPU深度学习环境出租平台。随着人工智能发展逐渐变成混合学科经验科学学科的深海区神器&#xff0c;一款高效的云GPU深度学习出租平台成为每一个深度学习的从业者的最大痛点。如何解决数据痛点&#xff0c;计算资源痛…

python--可重用的登录注册系统(上)

文章目录预期目标一、基本逻辑设计数据库模型二、前端界面设计与优化完善登录的视图函数三、session会话与登录的视图函数四、将项目上传到远程仓库预期目标 实现注册&#xff08;邮箱、手机、qq、微信&#xff09; 登录 注销等功能 路由配置 视图配置 数据库模型 模板&#xf…

生物系转行学编程,如今身家26亿

在编程界有许多明星级别的大牛&#xff0c;他们有些人学习成绩很差&#xff0c;有些人甚至不是科班出身&#xff0c;但对编程的狂热和努力&#xff0c;成就了他们在IT界“名利双收”的地位。 在我们中国编程界就有这样一位大牛&#xff0c;非科班出身&#xff0c;却做到了神一般…

el-pagination 动态切换每页条数、页数切换

目录 业务场景 官方链接 实现效果 使用框架 代码展示 template代码 script代码 变量定义 事件定义 handleSizeChange事件--实现每页条数改变表格动态变化 handleCurrentChange事件--切换页码 css代码 完整代码 总结 业务场景 当表格中的数据量如果非常庞大的时候我们…

【Javascript基础】--零基础--超详细且简洁的Javascript笔记--代码质量(03)

在浏览器中调试 在编写代码前看看调试。 调试是指在一个脚本中找出并修复错误的过程。 在这里我们将会使用 Chrome&#xff08;谷歌浏览器&#xff09;&#xff0c;因为它拥有足够多的功能&#xff0c;其他大部分浏览器的功能也与之类似。 “资源&#xff08;Sources&#…

为什么编程入门从Python学起?

目前&#xff0c;青岛市的小学、初中、高中对于编程教育和信息学的推进几乎都选中了Python。 浙江省新高中信息技术教材改革项目中&#xff0c;高中新生开始使用新教材&#xff0c;里面的编程语言将换用 Python&#xff0c;Python 将正式纳入高考内容。 Python是一种代表简单主…

看BP(后向投影算法)英文文献生词记录

看BP&#xff08;后向投影算法&#xff09;英文文献生词记录 总的来说&#xff0c;该论文是在讲CAT和SAR的后向投影算法之间的联系与区别 acoustic imaging 原声成像 polychromatic 美 [pɒlɪkroʊ’mtɪk] 英 [pɒlɪkrəʊ’mtɪk] adj.多色的 illumination 美 [ɪˌlum…

建筑“光储直柔”配用电系统关键技术分析

低碳发展背景下的建筑“光储直柔”配用电系统关键技术分析&#xff08;2021&#xff09; 摘 要 在低碳发展的背景下&#xff0c;为适应高比例的可再生能源结构&#xff0c;建筑电气化已经成为未来的发展趋势。建筑电气化不仅要提高建筑电气化率&#xff0c;还要发展新型建筑配…

RV1126笔记九:RTMP服务器搭建

若该文为原创文章,转载请注明原文出处 一、介绍 搭建RTMP服务器主要是为了在RV1126上实现RTMP推拉流功能测试使用,如果条件允许可以把RTMP服务器部署到公网服务器上,搭建的RTMP服务器只支持h264,h265需要自行修改。 这里介绍两种方式搭建RTMP服务器: 一、使用开源的SRS…