android.R.id.content作为Fragment的容器

时间:2014-07-12 10:58:55

标签: android android-layout android-fragments fragmenttransaction

我的情况是活动A,其中包含片段B.我总是像这样实现它。

活动A的布局:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/container"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

片段B的布局:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        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。这对我很有用。我删除了一个无用的包含。

我的问题是做这个“黑客”的好习惯。在任何情况下它都会崩溃我的应用程序吗?这个实现后我可以遇到什么问题?可能有人在这个问题上有经验吗?

感谢所有人的好答案。

1 个答案:

答案 0 :(得分:21)

它没有任何问题。就像你说的那样:你不需要额外的R.id.content布局,所以......不要用setContentView添加它。在ActionBar的官方文档中甚至提到了它:http://developer.android.com/guide/topics/ui/actionbar.html#Tabs

  

或者,如果选项卡内容将填充活动布局,那么   你的活动根本不需要布局(你甚至不需要   调用setContentView())。相反,您可以将每个片段放入   默认根视图,您可以参考   android.R.id.content ID

如果你只为14岁以上开发(因为原生ActionBar),一切都应该没问题,但是如果你使用支持lib,请阅读以下几点。

予。如果使用低于19的支持库版本:

重要的是:您开发的最低API级别是多少?

如果您的应用支持API&lt; 14,你使用AppCompat,你必须知道不同的行为。 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),则必须执行此操作。


II。如果您使用支持库版本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 (以及旧的android.R.id.content)替换旧的 R.id.action_bar_activity_content 与NO_ID)以获得更好的兼容性!因此,如果您使用Support Lib r19或更高版本(或仅仅是本机框架),您可以只使用&lt; 14和14+变体中的android.R.id.content:)