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


135

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

这是我的助手类:

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

Answers:


331

好吧,只要执行错误消息告诉您的内容即可。

不要打电话setContentView()之前requestFeature()

注意:

正如评论说,对于ActionBarSherlockAppCompat图书馆,有必要调用requestFeature()之前super.onCreate()


60
该死的,这是一个经典的答案。
2013年

60
对于ActionBarSherlock,还需要在requestFeature()之前调用super.onCreate()。参考:github.com/JakeWharton/ActionBarSherlock/issues/…–
Saran

1
如果您需要显示一种没有标题栏的布局,然后显示带有标题栏的布局怎么办?您将不得不先requestWindowFeature(Window.FEATURE_NO_TITLE)隐藏它,然后再setContentView()使用第一个布局,然后requestWindowFeature(Window.FEATURE_CUSTOM_TITLE)再次显示标题栏。那将是setContentView()第二次之后。
MSBG

35
AppCompat中的情况与@Saran相同。您必须requestFeature提前致电super.onCreate()
Jaison Brooks 2014年

7
这个答案并没有多大帮助...但是我知道什么
Ojonugwa Jude Ochalifu

23

我知道已经有一年多了,但是打电话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() );
       // ...
   }
}

*一些附加说明:

  1. 不要依赖隐藏标题。尽管未设置标题,但通常会有一个空白区域。
  2. 不要尝试使用页眉页脚和中间视图来构建自己的视图。如上所述,尽管请求FEATURE_NO_TITLE,标题仍可能不会完全隐藏。
  3. 不要使用颜色属性或文本大小来为内容视图设置样式。让该对话框处理该问题,否则,您将冒着将黑色文本放在深蓝色对话框中的风险,因为供应商将颜色反转了。

最初,我在onCreate()方法中发布了setTitle()和setIcon(),但编辑将其移至prepare()方法中,该方法在onPrepareDialog()方法期间被调用。
Cookster 2012年

2
感谢分享。我认为以下content = inflater.inflate(R.layout.custom_view, null);可能应该是content = li.inflate(R.layout.custom_view, null);。因此,inflater必须替换为li
aLearner 2012年

14

我正在扩展DialogFragment,以上答案没有用。我必须使用getDialog()实现删除标题:

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

@ojonugwaochalifu有一阵子了,所以我不记得确切了,但是我确定需要在setcontentView()方法之前完成
非法论点

1
对于任何面临相同问题的人:我在onViewCreated()中添加了此代码;
7geeky

2

错误不完全告诉您出了什么问题吗?您正在呼叫requestWindowFeaturesetFeatureInt然后再呼叫setContentView

顺便问一下,为什么要打setContentView两次电话?



1

更改编译SDK版本目标SDK版本生成工具版本24.0.0的build.gradle如果妳请求功能面临的问题


0

就我而言,我DialogFragment参加了Activity。在这个对话框片段中,我在DialogFragment中写道,删除黑色边框

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
}

或者删除setStyle(STYLE_NO_FRAME, 0)onCreate()或缠得/删除onCreateDialog。因为对话框创建后对话框设置已更改。


0

我在基于扩展DialogFragment的Dialogs上遇到了这个问题,该对话框在运行API 26的设备上可以正常运行,但在API 23上失败。上述策略不起作用,但是我通过删除onCreateView方法解决了该问题(该功能已由更多最新的Android Studio模板)从DialogFragment中创建并在onCreateDialog中创建对话框。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.