50

DialogFragmentでカスタム ビューを使用してを作成しようとしていますAlertDialog。このビューは、xml からインフレートする必要があります。私のDialogFragmentクラスでは:

@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
    return new AlertDialog.Builder(getActivity())
        .setTitle("Title")
        .setView(getActivity().getLayoutInflater().inflate(R.layout.dialog, null))
        .setPositiveButton(android.R.string.ok, this)
        .setNegativeButton(android.R.string.cancel, null)
        .create();
}

次のような他のインフレ方法を試し.setView()ました。

.setView(getActivity().getLayoutInflater().inflate(R.layout.dialog, (ViewGroup) getView(), false))

.setView(getActivity().getLayoutInflater().inflate(R.layout.dialog, (ViewGroup) getTargetFragment().getView(), false))

このダイアログを表示しているフラグメントにターゲットフラグメントを設定した後。

カスタム ビューを拡張しようとすると、次の例外が発生します。

E/AndroidRuntime(32352): android.util.AndroidRuntimeException: requestFeature() must be called before adding content
E/AndroidRuntime(32352):        at com.android.internal.policy.impl.PhoneWindow.requestFeature(PhoneWindow.java:214)
E/AndroidRuntime(32352):        at com.android.internal.app.AlertController.installContent(AlertController.java:248)
E/AndroidRuntime(32352):        at android.app.AlertDialog.onCreate(AlertDialog.java:314)
E/AndroidRuntime(32352):        at android.app.Dialog.dispatchOnCreate(Dialog.java:335)
E/AndroidRuntime(32352):        at android.app.Dialog.show(Dialog.java:248)
E/AndroidRuntime(32352):        at android.support.v4.app.DialogFragment.onStart(DialogFragment.java:339)
E/AndroidRuntime(32352):        at android.support.v4.app.Fragment.performStart(Fragment.java:1288)
E/AndroidRuntime(32352):        at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:873)
E/AndroidRuntime(32352):        at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1041)
E/AndroidRuntime(32352):        at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:625)
E/AndroidRuntime(32352):        at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1360)
E/AndroidRuntime(32352):        at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:411)
E/AndroidRuntime(32352):        at android.os.Handler.handleCallback(Handler.java:587)
E/AndroidRuntime(32352):        at android.os.Handler.dispatchMessage(Handler.java:92)
E/AndroidRuntime(32352):        at android.os.Looper.loop(Looper.java:132)
E/AndroidRuntime(32352):        at android.app.ActivityThread.main(ActivityThread.java:4028)
E/AndroidRuntime(32352):        at java.lang.reflect.Method.invokeNative(Native Method)
E/AndroidRuntime(32352):        at java.lang.reflect.Method.invoke(Method.java:491)
E/AndroidRuntime(32352):        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:844)
E/AndroidRuntime(32352):        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:602)
E/AndroidRuntime(32352):        at dalvik.system.NativeStart.main(Native Method)

を次のように使用しようとすると、次DialogFragmentgetLayoutInflator(Bundle)ようになります。

.setView(getLayoutInflater(savedInstanceState).inflate(R.layout.dialog, null))

を取得しStackOverflowErrorます。

AlertDialogのカスタムビューをインフレートする方法を知っている人はいDialogFragmentますか?

4

9 に答える 9

92

最初のエラー行は、これがダイアログ自体ではなく、ダイアログの作成方法に関連しているというヒントを与えてくれます。

ダイアログを自動的に作成していますか (これは、ビューがすべて設定される前に呼び出されることを意味する可能性があります)、またはボタンのクリックに応答して作成していますか? インスタンス化の順序が原因で、最初はフラグメントに問題がありました。

同じコードを使用してビューを設定しましたが、結果は機能します。これをよりきれいに見せるために他のセットアップを切り取りましたが、それがあってもなくても機能します。

@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
    AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());

    View view = getActivity().getLayoutInflater().inflate(R.layout.dialog_layout, null);
    builder.setView(view);

    return builder.create();
}
于 2012-01-17T20:01:58.197 に答える
23

これらの答えのどれも問題を解決しないので、私はこれらの答えに驚いています。

DialogFragment を使用すると、同じ UI をダイアログに再利用し、フラグメントとしてアプリに統合することができます。かなり便利な機能です。Google のドキュメントによると、onCreateDialog と onCreateView をオーバーライドすることでこれを実現できます。 http://developer.android.com/reference/android/app/DialogFragment.html

ここには 3 つのシナリオがあります。

  1. onCreateDialog のみをオーバーライド - ダイアログとして機能しますが、他の場所に統合することはできません。
  2. onCreateView のみをオーバーライド - ダイアログとしては機能しませんが、他の場所に統合できます。
  3. 両方をオーバーライド - ダイアログとして機能し、他の場所に統合できます。

解決策: AlertDialog クラスは、requestFeature を呼び出す別のクラスを呼び出しています。これを修正するには.. AlertDialog を使用しないでください。代わりに、プレーンなダイアログまたは super.onCreateDialog が返すものを使用してください。これは私が見つけた解決策が最も効果的です。

警告: DatePickerDialog、ProgressDialog、TimePickerDialog などの他のダイアログはすべて AlertDialog から継承されるため、同じエラーが発生する可能性があります。

結論: DialogFragment は、複数の場所で使用する必要がある非常にカスタマイズされたインターフェイスを作成する必要がある場合に適しています。既存の Android ダイアログを再利用してもうまくいかないようです。

于 2014-01-30T20:46:06.980 に答える
11

リクエスト機能のクラッシュを回避し、同じレイアウトを使用します:

public class MyCombinedFragment extends DialogFragment
{
    private boolean isModal = false;

    public static MyCombinedFragment newInstance()
    {
        MyCombinedFragment frag = new MyCombinedFragment();
        frag.isModal = true; // WHEN FRAGMENT IS CALLED AS A DIALOG SET FLAG
        return frag;
    }

    public MyCombinedFragment()
    {
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) 
    {
        if(isModal) // AVOID REQUEST FEATURE CRASH
        {
        return super.onCreateView(inflater, container, savedInstanceState);
        }
        else
        {
        View view = inflater.inflate(R.layout.fragment_layout, container, false);
        setupUI(view);
        return view;
        }
    }

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState)
    {
        AlertDialog.Builder alertDialogBuilder = null;
        alertDialogBuilder = new AlertDialog.Builder(getActivity());
        View view = getActivity().getLayoutInflater().inflate(R.layout.fragment_layout, null);
        alertDialogBuilder.setView(view);
        alertDialogBuilder.setTitle(“Modal Dialog“);
        alertDialogBuilder.setPositiveButton("Cancel", new DialogInterface.OnClickListener()
        {
            @Override
            public void onClick(DialogInterface dialog, int which)
            {
                dialog.dismiss();
            }
        });
        setupUI(view);
        return alertDialogBuilder.create();
    }
}
于 2014-02-08T08:13:35.180 に答える
2

私も同じ問題を抱えていました。私の場合、onCreateDialog で作成されたビューを返すのではなく、新しいビューを再インフレートするテンプレート onCreateView を Android Studio が作成したためです。onCreateView は onCreateDialog の後に呼び出されるため、解決策は単純にフラグメント ビューを返すことでした。

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    return this.getView();
}
于 2014-11-25T16:30:16.633 に答える
1

同じ問題に直面し、エラーを取り除くのに多くの時間がかかりました。最後に、リソース ID を setView() メソッドに渡すことで問題が解決しました。以下のようにセット ビューを追加します。

.setView(R.layout.dialog)

于 2015-12-09T05:53:04.227 に答える
0

代わりに、通常どおり onCreateView メソッドでカスタム ビューを作成します。ダイアログのタイトルを変更したい場合は、onCreateView で行います。

私が何を意味するかを説明する例を次に示します。

        @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        getDialog().setTitle("hai");
        View v = inflater.inflate(R.layout.fragment_dialog, container, false);
        return v;
    }

次に、次のように呼び出します。

DialogFragment df = new MyDialogFragment();
df.show(..);

ほら、独自のカスタム ビューを持つダイアログが表示されます。

于 2011-12-13T13:16:19.853 に答える
0

あなたが呼び出すコードで

 create().

と置換する

show().
于 2011-09-22T00:52:15.257 に答える
0

私は XML からインフレートしていませんが、DialogFragment で動的ビューの生成を成功させました:

@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
    m_editText = new EditText(getActivity());
    return new AlertDialog.Builder(getActivity())
            .setView(m_editText)
            .setPositiveButton(android.R.string.ok,null)
            .setNegativeButton(android.R.string.cancel, null);
            .create();
}
于 2011-11-03T21:29:57.077 に答える