Activity中setContentView浅析

2023-12-26 17:48

本文主要是介绍Activity中setContentView浅析,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

protected void onCreate(final Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);
}

setContentView()方法会将我们的视图设置到哪儿去了?

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

Activity会调用当前Activity的Window的setContentView()方法,而Window类是一个抽象类,唯一实现类PhoneWindow。

PhoneWindwo对象在Activity中的attach()方法中创建。

 final void attach(Context context, ActivityThread aThread,Instrumentation instr, IBinder token, int ident,Application application, Intent intent, ActivityInfo info,CharSequence title, Activity parent, String id,NonConfigurationInstances lastNonConfigurationInstances,Configuration config, String referrer, IVoiceInteractor voiceInteractor,Window window) {attachBaseContext(context);mFragments.attachHost(null /*parent*/);mWindow = new PhoneWindow(this, window);mWindow.setWindowControllerCallback(this);mWindow.setCallback(this);mWindow.setOnWindowDismissedCallback(this);mWindow.getLayoutInflater().setPrivateFactory(this);//......
}

那我们接着看PhoneWindow的setContentView()方法。

public void setContentView(int layoutResID) {if (mContentParent == null) {installDecor();} else if (!hasFeature(FEATURE_CONTENT_TRANSITIONS)) {mContentParent.removeAllViews();}if (hasFeature(FEATURE_CONTENT_TRANSITIONS)) {final Scene newScene = Scene.getSceneForLayout(mContentParent, layoutResID,getContext());transitionTo(newScene);} else {mLayoutInflater.inflate(layoutResID, mContentParent);}mContentParent.requestApplyInsets();final Callback cb = getCallback();if (cb != null && !isDestroyed()) {cb.onContentChanged();}
}

当我们第一此setContentView()时,mContentParent为空,会调用installDecor()方法做些初始化工作。然后再将我们setContentView里的View加载到mContentParent上面去。

mLayoutInflater.inflate(layoutResID, mContentParent)

来看看installDecor()做了什么伟大的事情:

private DecorView mDecor;private ViewGroup mContentParent;private ViewGroup mContentRoot;private void installDecor() {if (mDecor == null) {mDecor = generateDecor();mDecor.setDescendantFocusability(ViewGroup.FOCUS_AFTER_DESCENDANTS);mDecor.setIsRootNamespace(true);if (!mInvalidatePanelMenuPosted && mInvalidatePanelMenuFeatures != 0) {mDecor.postOnAnimation(mInvalidatePanelMenuRunnable);}}if (mContentParent == null) {mContentParent = generateLayout(mDecor);// Set up decor part of UI to ignore fitsSystemWindows if appropriate.mDecor.makeOptionalFitsSystemWindows();//....}
}

mDecor是DecorView类对象,而DecorView继承自FrameLayout,generateDecor()方法就是初始化创建一个空的FrameLayout。来看generateLayout()方法是怎样初始化我们需要的mContentParent的:

protected ViewGroup generateLayout(DecorView decor) {   TypedArray a = getWindowStyle();if (a.getBoolean(R.styleable.Window_windowNoTitle, false)) {requestFeature(FEATURE_NO_TITLE);} else if (a.getBoolean(R.styleable.Window_windowActionBar, false)) {requestFeature(FEATURE_ACTION_BAR);}if (a.getBoolean(R.styleable.Window_windowActionBarOverlay, false)) {requestFeature(FEATURE_ACTION_BAR_OVERLAY);}//....if ((features & (1 << FEATURE_SWIPE_TO_DISMISS)) != 0) {layoutResource = R.layout.screen_swipe_dismiss;} else if ((features & ((1 << FEATURE_LEFT_ICON) | (1 << FEATURE_RIGHT_ICON))) != 0) {if (mIsFloating) {TypedValue res = new TypedValue();getContext().getTheme().resolveAttribute(R.attr.dialogTitleIconsDecorLayout, res, true);layoutResource = res.resourceId;} else {layoutResource = R.layout.screen_title_icons;}removeFeature(FEATURE_ACTION_BAR);} else if ((features & ((1 << FEATURE_PROGRESS) | (1 << FEATURE_INDETERMINATE_PROGRESS))) != 0&& (features & (1 << FEATURE_ACTION_BAR)) == 0) {layoutResource = R.layout.screen_progress;} else if ((features & (1 << FEATURE_CUSTOM_TITLE)) != 0) {}//.....int layoutResource;//.....View in = mLayoutInflater.inflate(layoutResource, null);decor.addView(in, new ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT));mContentRoot = (ViewGroup) in;ViewGroup contentParent = (ViewGroup)findViewById(ID_ANDROID_CONTENT);//.....return contentParent;}

generateLayout()方法会根据我们Acivity主题样式,选择加载不同的系统布局资源,并将该视图添加到DecorView中去。

View in = mLayoutInflater.inflate(layoutResource, null);
decor.addView(in, new ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT));
mContentRoot = (ViewGroup) in;

无论选择哪一个布局资源里面都一个id名为content的FrameLayout。再从该布局中找到我们需要的contentParent。

(ViewGroup)findViewById(ID_ANDROID_CONTENT);

最后返回contentParent,将setContentView()中的视图加载到mContentParent上去。
这里写图片描述

这篇关于Activity中setContentView浅析的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/540298

相关文章

浅析如何使用Swagger生成带权限控制的API文档

《浅析如何使用Swagger生成带权限控制的API文档》当涉及到权限控制时,如何生成既安全又详细的API文档就成了一个关键问题,所以这篇文章小编就来和大家好好聊聊如何用Swagger来生成带有... 目录准备工作配置 Swagger权限控制给 API 加上权限注解查看文档注意事项在咱们的开发工作里,API

浅析Rust多线程中如何安全的使用变量

《浅析Rust多线程中如何安全的使用变量》这篇文章主要为大家详细介绍了Rust如何在线程的闭包中安全的使用变量,包括共享变量和修改变量,文中的示例代码讲解详细,有需要的小伙伴可以参考下... 目录1. 向线程传递变量2. 多线程共享变量引用3. 多线程中修改变量4. 总结在Rust语言中,一个既引人入胜又可

浅析Spring Security认证过程

类图 为了方便理解Spring Security认证流程,特意画了如下的类图,包含相关的核心认证类 概述 核心验证器 AuthenticationManager 该对象提供了认证方法的入口,接收一个Authentiaton对象作为参数; public interface AuthenticationManager {Authentication authenticate(Authenti

(入门篇)JavaScript 网页设计案例浅析-简单的交互式图片轮播

网页设计已经成为了每个前端开发者的必备技能,而 JavaScript 作为前端三大基础之一,更是为网页赋予了互动性和动态效果。本篇文章将通过一个简单的 JavaScript 案例,带你了解网页设计中的一些常见技巧和技术原理。今天就说一说一个常见的图片轮播效果。相信大家在各类电商网站、个人博客或者展示页面中,都看到过这种轮播图。它的核心功能是展示多张图片,并且用户可以通过点击按钮,左右切换图片。

风暴项目个性化推荐系统浅析

风暴项目的主要任务是搭建自媒体平台,作为主开发人员的我希望把工作重心放在个性化推荐系统上。 目前风暴项目的个性化推荐是基于用户行为信息记录实现的,也就是说对于每条资讯,数据库中有字段标明其类型。建立一张用户浏览表,对用户的浏览行为进行记录,从中可以获取当前用户对哪类资讯感兴趣。 若用户第一次登陆,则按默认规则选取热点资讯做推荐,及所有资讯按浏览量降序排序,取前4个。另外,我考虑到后期可能有商业

中国书法——孙溟㠭浅析碑帖《越州石氏帖》

孙溟㠭浅析碑帖《越州石氏帖》 《越州石氏帖》  是一部汇集多本摹刻的帖,南宋时期的会稽石邦哲(字熙明)把家藏的一些法书碑帖集中一起摹刻成的,宋理宗时临安书商陈思《宝刻丛编》有记載这部帖的目录。现在还存有宋代时拓的残缺本,大多是相传的晋朝唐朝的小楷,后人多有临摹学习,并以此版本重新摹刻。 (图片来源于网络) 图文/氿波整理

浅析网页不安装插件播放RTSP/FLV视频的方法

早期很多摄像头视频流使用的是RTSP、RTMP协议,播放这类协议的视频通常是在网页上安装插件。但现在越来越多的用户,对于网页安装插件比较反感,且随着移动设备的普及,用户更多的希望使用手机、平板等移动设备,直接可以查看这些协议的视频。那是否有什么方案可以直接网页打开RTSP、RTMP协议的视频,直接观看不用安装插件呢?而且对于摄像头的数据,尽可能低延迟的获取实时画面。  其实很多摄像头厂家也注意到

浅析c/c++中 struct的区别

(1)C的struct与C++的class的区别。 (2)C++中的struct和class的区别。 在第一种情况下,struct与class有着非常明显的区别。C是一种过程化的语言,struct只是作为一种复杂数据类型定义,struct中只能定义成员变量,不能定义成员函数(在纯粹的C语言中,struct不能定义成员函数,只能定义变量)。例如下面的C代码片断: 复制代码代码如下:

LeakCanary测试app内存泄露+registerActivityLifecycleCallbacks管理Activity的生命周期

public class MyApplication extends Application {private String tag = "MyApplication";private static Stack<Activity> activityStack;//检测内存泄露private RefWatcher refWatcher;@Overridepublic void onCreate()

android studio怎么修改创建的Activity的模板?

1.找到android studio的安装目录,如下图,找到对应文件,修改EmptyActivity的模板。 2.修改成如下: 3.新建的EmptyActivity的默认代码如下: