理解安卓的视图体系结构

文章详细介绍了Android中视图结构,包括Activity、Window、ContentView、DecorView、布局优化、Dialog、PopupWindow和Toast的使用及原理。强调了减少布局深度和广度对性能的影响,以及如何利用Dialog和PopupWindow实现即插即用的弹窗。同时,解释了为何Dialog显示需要Activity,以及如何创建全屏Dialog和PopupWindow。文章还提到了Toast的特点和限制,并给出了实战建议,主张优化Activity的Viewtree以提高性能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

原文链接 理解安卓的视图体系结构

当我们想要写一个页面的时候,通过一个Activity,然后调用其setContentView方法,把一个布局文件当作一个参数传递过去,然后一个页面就好了,但是除此之外,我们还需要与一些组件打交道,比如像Window,WindowManager,那么这些东西到底 与我们的页面布局有什么关系,今天就来学习一下,以便对整体窗口有个更清楚的认知。

布局是一颗View tree

先从一个最简单的例子出发,平时我们写一个页面,都从一个布局文件出发。这其实是在构建一个View tree,为啥一定是tree呢,因为我们的布局文件,无论有多么的复杂,都是从一个根(通常是一个ViewGroup对象)开始的,父布局里面再写子布局,比如这样的:

<LinearLayout id="app_root">
  <TextView id="label"/>
  <Button id="submit"/>
</LinearLayout>

这会形成一个树状结构:

| app_root

   |- label

   |- submit

作为一个开发者,写布局是我们再熟悉不过的了,主要就是用所熟悉的各种Layout和View一起来构建想要的页面。

所写的布局,最终会生成一颗View tree,是一个树状的数据结构,每一个节点都是一个View对象(ViewGroup和View)。因此,布局优化的一个是感觉重要的点就是要先减少View tree的深度(也即平时所说的减少布局的嵌套),再想办法减少广度(减少个数)。

那么,我们写的布局的父布局又是哪里呢?这就又涉及两个东西,一个叫做decorView和contentView的东西。

DecorView与ContentView

我们平常所见的屏幕窗口的根布局是一个叫做DecorView的东西,它是我们通常意义上整个屏幕的根节点,它包含了上面的Status bar和下方的Navigation bar,以及属于应用程序的中间部分。它的源码路径是frameworks/base/core/java/com/android/internal/policy/DecorView.java。它是一个真实的view,它是FrameLayout的子类。

它下面有一个id为android.R.id.content的FrameLayout,我们平时在Activity中调用setContent时所传过去的布局文件所生成的View tree都是添加在这个FrameLayout下面,所以,通常对于我们一个Activity来说,这个FrameLayout是直接意义上的根节点,我们所写的布局都是添加它下面的。

ContentView所引申出来的奇技淫巧

布局优化技巧

首先,一个是布局的优化技巧,可以减少View tree的层级:假如你写的布局中根节点也是一个FrameLayout,那么可以直接用merge节点,把子view全部都直接加挂到前面提到的系统创建的Activity的根布局上面。

<merge>
  <Text />
  <Button />
</merge>

这可以把View tree减少一个层级(深度减1)。

页面内即插即用的弹窗

每个Activity都被回挂在一个id是android.R.id.content的FrameLayout下面,利用这一点,可以做一些即插即用的弹窗,即插即用的意思是,不用写在布局里面,而且显示的时间是不固定的,可能很多时候都不显示,在某个特定的逻辑或者时间才显示。就好比某些电商特定节日的弹窗一样,这种东西,一年也显示不了几回,如果直接添加在布局里面(哪怕你用ViewStub),不够优雅,毕竟不是常规逻辑下会出现的页面,这时可以利用content来做一些即时弹窗:

FrameLayout container = activity.findViewById(android.R.id.content);
View pop = <create or inflate your own view>;
container.addView(pop);

只要你能获得到Activity的实例(这个并不难),那么就可以非常优雅的添加弹窗,逻辑代码和布局文件都会相当独立,甚至可以用插件形式来异步加载。再进一步,如果 添加一个WebView,那么就可以做得更加的前端化,实时化和定制化,好多电商的弹窗就是这么干的。

Window与WindowManager

作为应用开发者,我们看一个View tree其实就是一坨布局,这是站在一个非常小的角度去看的,但如果站在整体系统架构角度来看的话,就会发现应用程序所在的view tree仅是系统可视化窗口架构中的末端,View只是用来构建视图的基本砖块而已。对于整体View

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值