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

Posted

技术标签:

【中文标题】在添加内容之前必须调用 requestFeature()【英文标题】:requestFeature() must be called before adding content 【发布时间】:2011-05-14 02:29:28 【问题描述】:

我正在尝试实现自定义标题栏:

这是我的 Helper 类:

import android.app.Activity;
import android.view.Window;

public class UIHelper 
    public static void setupTitleBar(Activity c) 
        final boolean customTitleSupported = c.requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);

        c.setContentView(R.layout.main);

        if (customTitleSupported) 
            c.getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.titlebar);
        
    

这是我在 onCreate() 中调用它的地方:

@Override
public void onCreate(Bundle savedInstanceState) 
    super.onCreate(savedInstanceState);
    setupUI();


private void setupUI()
     setContentView(R.layout.main);
     UIHelper.setupTitleBar(this);

但我得到了错误:

requestFeature() must be called before adding content

【问题讨论】:

在这里回答:***.com/questions/16939814/… 【参考方案1】:

好吧,按照错误信息告诉你的去做。

不要在requestFeature()之前调用setContentView()

注意:

如 cmets 中所说,对于 ActionBarSherlockAppCompat 库,必须在 super.onCreate() 之前调用 requestFeature()

【讨论】:

该死的,这是一个优雅的答案。 对于ActionBarSherlock,还需要在super.onCreate()之前调用requestFeature()。参考:github.com/JakeWharton/ActionBarSherlock/issues/… 如果您需要显示一个没有标题栏的布局,然后显示一个有标题栏的布局怎么办?您必须使用requestWindowFeature(Window.FEATURE_NO_TITLE) 隐藏它,然后使用setContentView() 进行第一个布局,然后使用requestWindowFeature(Window.FEATURE_CUSTOM_TITLE) 再次显示标题栏。那将是在setContentView() 第二次之后。 它与@Saran 所说的 AppCompat 中的情况相同。你必须在super.onCreate()之前打电话给你的requestFeature 这个答案没有多大帮助......但我知道什么【参考方案2】:

我知道它已经存在一年多了,但致电 requestFeature() 从未解决我的问题。事实上我根本不叫它。

我认为这是夸大视图的问题。尽管我进行了所有搜索,但直到我尝试了不同的膨胀视图方法,我才找到合适的解决方案。

AlertDialog.Builder 是一种简单的解决方案,但如果您使用 onPrepareDialog() 更新该视图,则需要做大量工作。

另一种选择是利用 AsyncTask 进行对话。

我使用的最终解决方案如下:

public class CustomDialog extends AlertDialog 

   private View content;

   public CustomDialog(Context context) 
       super(context);

       LayoutInflater li = LayoutInflater.from(context);
       content = li.inflate(R.layout.custom_view, null);

       setUpAdditionalStuff(); // do more view cleanup
       setView(content);           
   

   private void setUpAdditionalStuff() 
       // ...
   

   // Call ((CustomDialog) dialog).prepare() in the onPrepareDialog() method  
   public void prepare() 
       setTitle(R.string.custom_title);
       setIcon( getIcon() );
       // ...
   

* 一些附加说明:

    不要依赖隐藏标题。尽管没有设置标题,但通常会出现空白。 不要尝试使用页眉页脚和中间视图构建自己的视图。如上所述,尽管请求 FEATURE_NO_TITLE,但标头可能不会完全隐藏。 不要使用颜色属性或文本大小来过多地设置内容视图的样式。让对话框来处理,否则您可能会将黑色文本放在深蓝色对话框上,因为供应商会反转颜色。

【讨论】:

最初我在 onCreate() 方法中发布了 setTitle() 和 setIcon(),但编辑将其移至在 onPrepareDialog() 方法期间调用的 prepare() 方法。 感谢分享。我认为以下行content = inflater.inflate(R.layout.custom_view, null); 应该是content = li.inflate(R.layout.custom_view, null);。因此,inflater 必须替换为 li【参考方案3】:

我正在扩展一个 DialogFragment 并且上面的答案不起作用。我不得不使用 getDialog() 来实现删除标题:

getDialog().getWindow().requestFeature(Window.FEATURE_NO_TITLE);

【讨论】:

@ojonugwaochalifu 有一段时间了,所以我不记得了,但我确信它需要在 setcontentView() 方法之前完成 对于任何面临同样问题的人:我在 onViewCreated(); 中添加了这段代码;【参考方案4】:

对于 SDK 版本 23 及更高版本,如果您使用 AppCompatActivity 扩展您的活动,则会引发相同的 RuntimeException。如果您的 Activity 直接来自 Activity,则不会发生这种情况。

这是https://code.google.com/p/android/issues/detail?id=186440 中提到的 google 上的一个已知问题

为此提供的解决方法是使用 supportRequestWindowFeature() 方法而不是使用 requestFeature()。

如果解决了你的问题,请点赞。

【讨论】:

【参考方案5】:

就我而言,我在Activity 中显示了DialogFragment。在这个对话框片段中,我写了DialogFragment remove black border:

override fun onCreate(savedInstanceState: Bundle?) 
    super.onCreate(savedInstanceState)
    setStyle(STYLE_NO_FRAME, 0)


override fun onCreateDialog(savedInstanceState: Bundle?): Dialog 
    super.onCreateDialog(savedInstanceState)

    val dialog = Dialog(context!!, R.style.ErrorDialogTheme)
    val inflater = LayoutInflater.from(context)
    val view = inflater.inflate(R.layout.fragment_error_dialog, null, false)
    dialog.setTitle(null)
    dialog.setCancelable(true)
    dialog.setContentView(view)
    return dialog

onCreate() 中删除setStyle(STYLE_NO_FRAME, 0) 或更改/删除onCreateDialog。因为对话框设置会在对话框创建后更改。

【讨论】:

【参考方案6】:

错误是否准确地告诉您出了什么问题?在调用 setContentView 之后,您将调用 requestWindowFeaturesetFeatureInt

对了,你为什么要给setContentView打两次电话?

【讨论】:

【参考方案7】:

编译SDK版本目标SDK版本改为构建工具版本改为24.0.0在build.gradle 如果您在请求功能中遇到问题

【讨论】:

【参考方案8】:

我在基于扩展 DialogFragment 的 Dialogs 上遇到了这个问题,它在运行 API 26 的设备上运行良好,但在 API 23 上失败。上述策略不起作用,但我通过删除 onCreateView 方法解决了这个问题(已添加来自 DialogFragment 并在 onCreateDialog 中创建对话框。

【讨论】:

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

记录requestFeature() must be called before adding content问题

记录requestFeature() must be called before adding content问题

requestFeature() must be called before adding content

片段必须在创建之前调用寄存器 registerForActivityResult()

在片段中实现对话框时,必须在添加内容之前请求窗口功能

在 applicationDidFinishLaunching 之前调用 viewDidLoad