Ich versuche, ein DialogFragment mit meinem eigenen Layout zu erstellen.
Ich habe ein paar verschiedene Ansätze gesehen. Manchmal wird das Layout in OnCreateDialog folgendermaßen festgelegt: (Ich verwende Mono, habe mich aber etwas an Java gewöhnt.)
public override Android.App.Dialog OnCreateDialog (Bundle savedInstanceState)
{
base.OnCreateDialog(savedInstanceState);
AlertDialog.Builder b = new AlertDialog.Builder(Activity);
//blah blah blah
LayoutInflater i = Activity.LayoutInflater;
b.SetView(i.Inflate(Resource.Layout.frag_SelectCase, null));
return b.Create();
}
Dieser erste Ansatz funktioniert für mich ... bis ich ihn verwenden möchte. findViewByID.
Nach einigem googeln habe ich den zweiten Ansatz ausprobiert, bei dem es um das Überschreiben gehtOnCreateView
Also habe ich zwei Zeilen OnCreateDialog
auskommentiert, die das Layout festlegen, und dann Folgendes hinzugefügt:
public override Android.Views.View OnCreateView (LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
View v = inflater.Inflate(Resource.Layout.frag_SelectCase, container, false);
//should be able to use FindViewByID here...
return v;
}
was mir einen schönen Fehler gibt:
11-05 22:00:05.381: E/AndroidRuntime(342): FATAL EXCEPTION: main
11-05 22:00:05.381: E/AndroidRuntime(342): android.util.AndroidRuntimeException: requestFeature() must be called before adding content
Ich bin ratlos.
java
android
mono
xamarin.android
android-inflate
gghuffer
quelle
quelle
Antworten:
Ich würde vermuten, dass Sie nicht
findViewById()
auf die von zurückgegebene Ansicht zugreifen.inflate()
Versuchen Sie Folgendes :View view = i.inflate(Resource.Layout.frag_SelectCase, null); // Now use view.findViewById() to do what you want b.setView(view); return b.create();
quelle
requestFeature(...)
(oder so ähnlichrequestWindowFeature(Window.FEATURE_NO_TITLE);
) (wie in der Ausnahmemeldung bereits angegeben).Ich hatte die gleiche Ausnahme mit dem folgenden Code:
public class SelectWeekDayFragment extends DialogFragment { @Override public Dialog onCreateDialog(Bundle savedInstanceState) { return new AlertDialog.Builder(getActivity()) .setMessage("Are you sure?").setPositiveButton("Ok", null) .setNegativeButton("No way", null).create(); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.week_day_dialog, container, false); return view; } }
Sie müssen festlegen , dass nur eines von onCreateView oder onCreateDialog in einem DialogFragment überschrieben wird. Das Überschreiben beider führt zur Ausnahme: "requestFeature () muss vor dem Hinzufügen von Inhalten aufgerufen werden".
Wichtig
Eine vollständige Antwort finden Sie im Kommentar @TravisChristian. Wie er sagte, können Sie beide zwar überschreiben, aber das Problem tritt auf, wenn Sie versuchen, die Ansicht aufzublasen, nachdem Sie die Dialogansicht bereits erstellt haben.
quelle
Der folgende Code stammt aus dem Google-Handbuch. Die Antwort lautet also, dass Sie Ihren in onCreateDialog () nicht mögen könnten. Sie müssen super.onCreateDialog () verwenden, um einen Dialog zu erhalten.
public class CustomDialogFragment extends DialogFragment { /** The system calls this to get the DialogFragment's layout, regardless of whether it's being displayed as a dialog or an embedded fragment. */ @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // Inflate the layout to use as dialog or embedded fragment return inflater.inflate(R.layout.purchase_items, container, false); } /** The system calls this only when creating the layout in a dialog. */ @Override public Dialog onCreateDialog(Bundle savedInstanceState) { // The only reason you might override this method when using onCreateView() is // to modify any dialog characteristics. For example, the dialog includes a // title by default, but your custom layout might not need it. So here you can // remove the dialog title, but you must call the superclass to get the Dialog. Dialog dialog = super.onCreateDialog(savedInstanceState); dialog.requestWindowFeature(Window.FEATURE_NO_TITLE); return dialog; } }
quelle
onCreateDialog()
Methode nicht erwähnt . WirdonCreateView()
in diesem Fall helfen?Hier ist ein Beispiel für die Verwendung von findViewById in einem Dialogfragment
public class NotesDialog extends DialogFragment { private ListView mNotes; private RelativeLayout addNote; public NotesDialog() { // Empty constructor required for DialogFragment } @Override public Dialog onCreateDialog(Bundle savedInstanceState) { AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); View view = getActivity().getLayoutInflater().inflate(R.layout.note_dialog, null); mNotes = (ListView) view.findViewById(R.id.listViewNotes); addNote = (RelativeLayout) view.findViewById(R.id.notesAdd); addNote.setOnClickListener(new View.OnClickListener(){ @Override public void onClick(View v){ getDialog().dismiss(); showNoteDialog(); } }); builder.setView(view); builder.setTitle(bandString); builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) { getDialog().dismiss(); } } ); return builder.create(); }
quelle
Wie @Xavier Egea sagt, besteht bei der Implementierung von onCreateView () und onCreateDialog () die Gefahr, dass der Absturz "requestFeature () muss vor dem Hinzufügen von Inhalten aufgerufen werden" auftritt. Dies liegt daran, dass sowohl onCreateDialog () als auch onCreateView () aufgerufen werden, wenn Sie dieses Fragment als Dialog anzeigen () (warum, ich weiß nicht). Wie Travis Christian erwähnt hat, verursacht das Aufblasen () in onCreateView (), nachdem ein Dialog in onCreateDialog () erstellt wurde, den Absturz.
Eine Möglichkeit, diese beiden Funktionen zu implementieren, aber diesen Absturz zu vermeiden: Verwenden Sie getShowsDialog (), um die Ausführung von onCreateView () einzuschränken (sodass inflate () nicht aufgerufen wird). Auf diese Weise wird nur Ihr onCreateDialog () - Code ausgeführt, wenn Sie Ihr DialogFragment als Dialog anzeigen. Ihr onCreateView () - Code kann jedoch aufgerufen werden, wenn Ihr DialogFragment als Fragment in einem Layout verwendet wird.
// Note: if already have onCreateDialog() and you only ever use this fragment as a // dialog, onCreateView() isn't necessary @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { if (getShowsDialog() == true) { // **The key check** return super.onCreateView(inflater, container, savedInstanceState); } else { View view = getActivity().getLayoutInflater().inflate(R.layout.fragment_alarm_dialog, null); return configureDialogView(view); } } @Override public Dialog onCreateDialog(Bundle savedInstanceState) { // Return custom dialog... Dialog dialog = super.onCreateDialog(savedInstanceState); // "new Dialog()" will cause crash View view = getActivity().getLayoutInflater().inflate(R.layout.fragment_alarm_dialog, null); configureDialogView(view); dialog.setContentView(view); return dialog; } // Code that can be reused in both onCreateDialog() and onCreateView() private View configureDialogView(View v) { TextView myText = (TextView)v.findViewById(R.id.myTextView); myText.setText("Some Text"); // etc.... return v; }
quelle
Wenn Sie einfachen Zugriff auf die Dialogfeldeigenschaften wie den Titel und die Schaltfläche zum Schließen haben möchten, aber auch Ihr eigenes Layout verwenden möchten, können Sie mit Ihrem Builder einen LayoutInflator verwenden, wenn Sie onCreateDialog überschreiben.
@Override public Dialog onCreateDialog(Bundle savedInstanceState) { LayoutInflater inflater = getActivity().getLayoutInflater(); AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); builder.setMessage("Message!") .setTitle(this.dialogTitle) .setView(inflater.inflate(R.layout.numpad_dialog, null)) .setPositiveButton(R.string.enter, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { // Clicked 'Okay' } }) .setNegativeButton(R.string.dismiss, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { // Clicked 'Cancel' } }); return builder.create(); }
quelle