【问题标题】:requestFeature() must be called before adding content在添加内容之前必须调用 requestFeature()
【发布时间】: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

【问题讨论】:

标签: android android-layout android-activity


【解决方案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() );
       // ...
   }
}

* 一些附加说明:

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

【讨论】:

  • 最初我在 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 中创建对话框。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2014-11-21
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多