android.R.id.content 作为 Fragment 的容器
Posted
技术标签:
【中文标题】android.R.id.content 作为 Fragment 的容器【英文标题】:android.R.id.content as container for Fragment 【发布时间】:2014-09-02 22:26:06 【问题描述】:我的情况是包含 Fragment B 的 Activity A。我总是这样实现它。
活动 A 的布局:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/container"
android:layout_
android:layout_ />
片段 B 的布局:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_
android:layout_>
<Button
android:id="@+id/button"
android:layout_
android:layout_
android:text="@string/button_title"
android:layout_centerInParent="true"
android:background="@drawable/green_button"
android:textColor="@android:color/white"/>
</RelativeLayout>
这很好用,但是如果我们打开 Android 设备监视器并查看 View Hierarchy:
所以,我不喜欢在我的层次结构中有两个相同的无用 FrameLayouts,我可以剪切我的 R.id.container。我是这样做的:
我的活动 A 中的 onCreate(Bundle args) 实现:
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
getFragmentManager().beginTransaction()
.add(android.R.id.content, FragmentB.newInstance()).commit();
我只是没有为我的 Activity 设置内容,而是将我的 Fragment B 附加到系统容器 android.R.id.content。这对我很有用。我删除了一个无用的包含。
我的问题是做这个“hack”是个好习惯。它会在任何情况下使我的应用程序崩溃吗?在此实施后我会遇到什么问题?可能有人在这个问题上有有用的经验吗?
感谢大家的好回答。
【问题讨论】:
same
不,android.R.
【参考方案1】:
这并没有什么问题。就像你说的:你不需要额外的 R.id.content 布局,所以......只是不要用 setContentView 添加它。 ActionBar 的官方文档中甚至有提及:http://developer.android.com/guide/topics/ui/actionbar.html#Tabs
或者,如果选项卡内容将填充活动布局,则 您的活动根本不需要布局(您甚至不需要 调用 setContentView())。相反,您可以将每个片段放在 默认根视图,您可以使用 android.R.id.content ID
如果你只为 14+ 开发(因为原生 ActionBar)一切都应该没问题,但如果你使用支持库,请阅读以下几点。
我。如果您使用低于 19 的支持库版本:
重要的是:您开发的最低 API 级别是多少? 如果您的应用支持 API android.R.id.content 是您的应用程序应显示其内容的屏幕部分。 在原生 API 14+ 这只是 ActionBar 下方的部分,因为这部分应该显示活动内容。 在 AppCompat 中,没有对 ActionBar 的原生支持。 android.R.id.content 是整个应用屏幕的容器。这意味着 - 包括 ActionBar,因为 ActionBar 在那里被模拟并作为标准视图层次结构添加。要解决此问题,您必须检查您是否使用低于 14 的 API 并使用不同的 id:R.id.action_bar_activity_content
您可以创建辅助方法来获取正确的 id:
public static int getContentViewId()
return Build.VERSION.SDK_INT>=Build.VERSION_CODES.ICE_CREAM_SANDWICH ? android.R.id.content : R.id.action_bar_activity_content;
因此,如果您正在为 14 岁以上的用户开发,这是一个非常好的解决方案。如果您使用自定义 ActionBar 实现(如 AppCompat),则必须这样做。
二。如果您使用支持库修订版 19(或更高版本):
似乎此行为已在支持库修订版 19 中得到修复: https://code.google.com/p/android/issues/detail?id=58108#c21
http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/4.4.2_r1/android/support/v7/app/ActionBarActivityDelegateBase.java/#228
您可以看到他们用标准的 android.R.id.content 替换了旧的 R.id.action_bar_activity_content(以及旧的 android.R.id.content带 NO_ID)以获得更好的兼容性!因此,如果您使用 Support Lib r19 或更高版本(或仅使用本机框架),您可以只使用
【讨论】:
没问题。很高兴我能提供帮助:)我还稍微重新组织了我的答案+在顶部添加了 ActionBar 文档的链接(和引用)(确切地提到了这个特殊案例) 这很奇怪。我在支持库 v20 上使用了 android.R.id.content,但它不起作用。唯一有效的是使用布局文件并在其上使用 setContentView。 这似乎在 appcompat >= v22 中再次被破坏(它在 v21 上对我有用,但升级到 v22 或 v23 会中断,并放入我自己的内容 FrameLayout 修复它)以上是关于android.R.id.content 作为 Fragment 的容器的主要内容,如果未能解决你的问题,请参考以下文章