从当前活动获取根视图

725

我知道如何使用View.getRootView()来获取根视图。我也可以在button的onClick事件中获取视图,其中参数是一个View。但是我该如何获取一个activity中的view呢?


3
在应用程序中,通常您会使用setContentView()来指定要渲染的资源,并且您提供的视图已经是根视图。如果您需要该视图的处理句柄,只需在XAML中为其添加一个ID,然后使用findViewById()即可。 - xandy
我的计划是动态地附加代码..因此,如果我的用户使用API,我希望它能自动检测事物.. Boulder的解决方案有效! - Lalith
5
@xandy: 有一个小笔误:XAML -> XML。 - superjos
12个回答

1170

如果你需要获取你的活动的根视图(这样你就可以在上面添加内容),请使用:

findViewById(android.R.id.content).getRootView()

还有报道称,在某些设备上,你必须使用

getWindow().getDecorView().findViewById(android.R.id.content)
请注意,正如Booger所报告的那样,这可能会在某些设备上被导航栏(带有返回按钮等)遮挡住(但似乎在大多数设备上不是这样)。
如果您需要获取使用setContentView()方法添加到活动中的视图,则可以像pottedmeat所写的那样使用。
final ViewGroup viewGroup = (ViewGroup) ((ViewGroup) this
            .findViewById(android.R.id.content)).getChildAt(0);

但更好的方式是在XML布局中为该视图设置ID,并使用该ID。


203
实际上,只有findViewById(android.R.id.content)可以为我提供根视图。如果在某些情况下这不成立,我可以通过findViewById(android.R.id.content).getRootView()获取根视图。感谢您的回答。我在哪里可以了解更多关于android.R的内容?我之前不知道它的存在。 - Lalith
5
你可以在这里查看 http://developer.android.com/reference/android/R.html 这是Android资源参考。个人而言,我是通过在HierarchyViewer中检查布局来了解android.R.id.content的。 - Dmitry Ryadnenko
14
我注意到这个视图似乎包括状态栏,因此如果你正在寻找活动的可见部分,请使用@pottedmeat的答案。 - Ben Clayton
6
@Lalith,你能详细说明一下什么情况下需要执行findViewById(android.R.id.content).getRootView()吗?了解一个通用的规则将非常有用。 - batbrat
2
@batbrat 当使用操作栏时,我需要在Android 5.0+中使用.getRootView()。 - Morten Holmgaard
显示剩余10条评论

278

以下是我用来获取根视图的代码,它对应于使用 setContentView 方法分配的 XML 文件中的视图:

final ViewGroup viewGroup = (ViewGroup) ((ViewGroup) this
            .findViewById(android.R.id.content)).getChildAt(0);

33
这个答案提供了没有状态栏的视图 - 这正是我想要的。 我在寻找活动可见部分的像素宽度 + 高度。这个答案可以,谢谢! - Ben Clayton
9
这不包括ActionBar! - Wayne
5
有没有一种方法可以将“ActionBar”也包含在内? - theblang
3
关键词是“在XML文件中找到的根视图”。谢谢。 - Kacy
3
这应该是正确的标记答案。这将把 Snackbar 放置在您的活动中(在根目录),这正是它应该在的位置(我很确定没有人想把自己的信息放在导航按钮后面)。 - Booger
显示剩余2条评论

150

我只在 Android 4.0.3 上测试过这个:

getWindow().getDecorView().getRootView()

给出与我们从中获取的相同视图

anyview.getRootView();

com.android.internal.policy.impl.PhoneWindow$DecorView@#########
并且
getWindow().getDecorView().findViewById(android.R.id.content)
给予子元素它的样式。
android.widget.FrameLayout@#######
请确认。

5
Android2.3.3 看起来一样。 - ruX
2
适用于4.3版本,是我找到的最简单且代码量最少的方法。 - Oliver Dixon
11
最好使用SnackBar。 - zackygaurav
getWindow().getDecorView().getRootView().getHeight() 返回显示屏幕高度。 - vovahost
4
不建议在 Snackbar 中使用 getWindow().getDecorView().getRootView(),因为它会重叠系统导航栏。建议改用 findViewById(android.R.id.content)。 - thanhbinh84

36

获取当前活动的根视图。

在我们的活动中,我们可以使用以下代码获取root视图:

ViewGroup rootView = (ViewGroup) ((ViewGroup) this
            .findViewById(android.R.id.content)).getChildAt(0);
或者
View rootView = getWindow().getDecorView().getRootView();

35

在 Kotlin 中我们可以稍微简短一些:

val rootView = window.decorView.rootView

2
如果使用Windows系统,展示一个快捷方式时,在导航栏中显示相关信息。 - Campino

22

如果有人需要更简单的方式,请注意以下代码:

以下代码可查看整个活动:

View v1 = getWindow().getDecorView().getRootView();

要获取活动中特定的视图,例如活动内部的imageView,只需添加该视图的id即可:

View v1 = getWindow().getDecorView().getRootView().findViewById(R.id.imageView1);

希望这能对某人有所帮助


7
如果你想要获取特定的视图,可以在Activity中调用findViewById(R.id.imageView1); - RobCo

10

Kotlin扩展解决方案

使用此方法可以简化在Activity中的访问。然后,您可以直接从Activity中引用rootView,或者在Activity之外使用activity.rootView:

val Activity.rootView get() = window.decorView.rootView

如果您想要保持一致性,为片段添加相同的内容,请添加:

val Fragment.rootView get() = view?.rootView

8
对于那些正在使用Data Binding Library的人来说,要获取当前活动的根视图,只需使用以下代码:
View rootView = dataBinding.getRoot();

对于Kotlin用户来说,这甚至更简单:

val rootView = dataBinding.root

1
我认为这应该得到点赞,特别是现在数据绑定是处理视图的支持库。数据绑定使这个过程变得更加简单! - adonese

5
anyview.getRootView(); 是最简单的方法。

1

获取当前 Activity 的视图

在任何 onClick 中,我们都将获得 "View view",通过使用 'view' 获取 rootView。

View view = view.getRootView();

要在 Fragment 中获取视图

View view = FragmentClass.getView();


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接