web-dev-qa-db-ja.com

requestFeature()は、コンテンツを追加する前に呼び出す必要があります

私はカスタムタイトルバーを実装しようとしています:

これが私のヘルパークラスです。

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
133
Sheehan Alam

エラーメッセージに示されていることを実行してください。

setContentView()の前にrequestFeature()を呼び出さないでください。

注:

コメントで述べたように、ActionBarSherlockAppCompatライブラリの両方について、requestFeature()の前にsuper.onCreate()を呼び出す必要があります

324

私はそれが1年以上前であることを知っていますが、requestFeature()を呼び出しても問題は解決しませんでした。実際、私はそれをまったく呼びません。

それは私が思うにビューを膨らませることに関する問題でした。すべての検索にもかかわらず、ビューを拡大するさまざまな方法をいじるまで、適切な解決策を見つけることができませんでした。

AlertDialog.Builderは簡単なソリューションですが、onPrepareDialog()を使用してそのビューを更新する場合、多くの作業が必要です。

もう1つの方法は、ダイアログに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. コンテンツビューを色属性やテキストサイズで大きくスタイル設定しないでください。それ以外の場合は、ベンダーが色を反転したため、濃い青のダイアログに黒のテキストを配置する危険があります。
23
Cookster

DialogFragmentを拡張していましたが、上記の答えは機能しませんでした。タイトルを削除するにはgetDialog()を使用する必要がありました。

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

エラーは何が間違っているのかを正確に教えてくれませんか? requestWindowFeatureを呼び出した後、setFeatureIntsetContentViewを呼び出しています。

ところで、なぜsetContentViewを2回呼び出すのですか?

2
EboMike

SDKバージョンのコンパイルターゲットSDKバージョンビルドツールバージョン24.0. in build.gradleリクエスト機能で問題に直面した場合

1
Jaichander

SDKバージョン23以降では、AppCompatActivityを使用してアクティビティを拡張している場合、同じRuntimeExceptionがスローされます。アクティビティがアクティビティから直接派生している場合は発生しません。

これは https://code.google.com/p/Android/issues/detail?id=18644 に記載されているGoogleの既知の問題です。

このために提供される回避策は、requestFeature()を使用する代わりにsupportRequestWindowFeature()メソッドを使用することです。

それがあなたの問題を解決するならば、賛成してください。

1
Keshav Bansal

API 26を実行しているデバイスでは正常に機能したが、API 23で失敗した拡張DialogFragmentに基づくダイアログでこの問題が発生しました。上記の戦略は機能しませんでしたが、onCreateViewメソッド( DialogFragmentからの最近のAndroid St​​udioテンプレート)およびonCreateDialogでダイアログを作成します。

0
BillC

私の場合、DialogFragmentActivityを示しました。このダイアログフラグメントでは、 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
}

setStyle(STYLE_NO_FRAME, 0)onCreate()を削除するか、onCreateDialogを変更/削除します。ダイアログが作成された後にダイアログ設定が変更されたため。

0
CoolMind