在 Fragment 中添加内容之前必须调用 requestFeature()

Posted

技术标签:

【中文标题】在 Fragment 中添加内容之前必须调用 requestFeature()【英文标题】:requestFeature() must be called before adding content in Fragment 【发布时间】:2014-11-21 01:48:39 【问题描述】:
android.util.AndroidRuntimeException: requestFeature() must be called before adding content

我在使用时遇到此错误

getActivity().getWindow().requestFeature(Window.FEATURE_ACTION_BAR_OVERLAY);

来自片段。 我只想在这个片段中更改操作栏样式。所以我不能在MainActivity 中设置它。如何解决?

我看到了这个问题requestFeature() must be called before adding content 它没有说明如何从片段中解决这个问题

【问题讨论】:

在你调用 setContentView() 之前你应该把getActivity().getWindow().requestFeature(Window.FEATURE_ACTION_BAR_OVERLAY); ***.com/questions/4250149/… 【参考方案1】:

我在使用 DialogFragment 时也遇到了这个错误,即使我根本没有调用 requestFeature()。

我从 DialogFragment 的 onActivitiyCreate() 调用 getDecorView() 作为我编写的一些跟踪代码的一部分,以帮助我了解创建 Windows 的方式和时间。这工作得很好,但是在片段的生命周期稍后,它的 onStart() 方法被调用了。这称为 Dialog 的 show() 最终调用 AlertDialog 的 onCreate() 最终调用 PhoneWindow 的 requestFeature() 方法来请求 Window.FEATURE_NO_TITLE。

由于调用 getDecorView() “第一次‘锁定’各种窗口特征,如 setContentView(View, android.view.ViewGroup.LayoutParams) 中所述。”,这违反了“requestFeature() 之前被调用的要求”在 Fragment 中添加内容”——微妙之处在于,我调用 getDecorView() 间接添加了内容。

解决方法是调用 peekDecorView() 而不是 getDecorView()。

【讨论】:

哇。你基本上救了我的命。我们在生产中遇到了一个错误,它使用“requestFeature()”stracktrace 使应用程序崩溃。在过去的两天里,我们无法追踪到它——直到我偶然发现了你的帖子。我们还在 DialogFragment 上调用 getDecorView。我改变了它,我想它有效!我仍然不能 100% 确定这是否真的以各种可能的方式解决了整个问题,但我们似乎走在了一个好路上!谢谢。【参考方案2】:

如果您使用 AppCompatActivity 作为 Activity 的父级,则无论人们如何响应,此问题仍然会出现。

对我来说,这段代码会抛出错误:​

protected void onCreate(Bundle savedInstanceState) 
    super.onCreate(savedInstanceState);
    getWindow().requestFeature(Window.FEATURE_PROGRESS);
    setContentView(R.layout.activity_browser);

测试 1:MyActivity extends Activity ==> 工作 测试 2:MyActivity extends AppCompatActivity ==> 错误“在活动中添加内容之前必须调用 requestFeature()”

测试 2(如果您使用 Appcompat)的解决方案是调用 requestFeature 之前 super.onCreate。它会解决你的问题。

【讨论】:

【参考方案3】:

您必须在 Activity 的 onCreate() 方法中的 setContentView() 之前调用 getWindow().requestFeature(Window.FEATURE_ACTION_BAR_OVERLAY);。您必须将此行添加到您的 FragmentActivity 中,从那里调用您的 Fragment

【讨论】:

有多个片段。我只希望在特定片段中使用此功能。因此,如果在父活动中设置此功能,所有其他片段都有此功能 @Sunny 因为你必须制作自定义主题并将其应用于你的片段类【参考方案4】:

requestFeature() 应在您的活动中在 setContentView() 之前调用。 从 Fragment 调用 getActivity().getWindow().requestFeature() 是不好的做法。如果您希望延迟操作栏的可见性,我建议您在活动的onCreate() 中隐藏操作栏,并在片段中的onViewCreated() 中取消隐藏。

【讨论】:

我只想在这个片段中做一个透明的actionbar 在这种情况下你需要重新创建你的活动,或者使用一些自定义视图而不是原生操作栏 有导航抽屉。所以自定义视图是不可能的 您可以隐藏您的原生操作栏并在出现此片段时显示您的自定义视图。【参考方案5】:

您需要为此片段创建一个单独的 Activity,然后在 setContentView() 之前对该 Activity 进行 requestFeature(),因为 requestFeature() 是 android.view.Window 的方法。窗口功能是针对特定活动的。您可以为特定活动而不是特定片段操作窗口行为。

【讨论】:

以上是关于在 Fragment 中添加内容之前必须调用 requestFeature()的主要内容,如果未能解决你的问题,请参考以下文章

FragmentPagerAdapter动态添加fragment和删除fragment

在 Fragment 中添加 onOptionsItemSelected 调用

Fragment.onstart 在 Activity.onstart 之前被调用

在活动的 onCreate 之前调用 Fragment 的 onCreateView

在back-stack中添加同一个fragment的多个实例,之前添加的实例的数据仍然存在

在通过 ActionBar 添加的 Fragment 上调用 addToBackStack()