Пользовательский макет для DialogFragment OnCreateView и OnCreateDialog

Я пытаюсь создать DialogFragment, используя свой собственный макет.

Я видел пару разных подходов. Иногда макет устанавливается в OnCreateDialog следующим образом: (Я использую Mono, но я немного привык к Java)

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(); } 

Этот первый подход работает для меня … пока я не хочу использовать findViewByID. поэтому после небольшого количества поисковых запросов я попробовал второй подход, который включает переопределение OnCreateView

Поэтому я прокомментировал две строки OnCreateDialog которые установили Layout, а затем добавили следующее:

 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; } 

который дает мне прекрасную ошибку:

 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 

Я в тупике.

Этот первый подход работает для меня … пока я не хочу использовать FindViewByID.

Я бы предположил, что вы не просматриваете findViewById() в представлении, возвращаемом inflate() , попробуйте следующее:

 View view = i.inflate(Resource.Layout.frag_SelectCase, null); // Now use view.findViewById() to do what you want b.setView(view); return b.create(); 

У меня было то же исключение со следующим кодом:

 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; } } 

Вы должны выбрать переопределить только один из onCreateView или onCreateDialog в диалоговом окне диалога. Исключение обоих приведет к исключению: «requestFeature () необходимо вызвать перед добавлением содержимого».

Важный

Для полного ответа проверьте комментарий @TravisChristian. По его словам, вы можете переопределить оба варианта, но проблема возникает, когда вы пытаетесь раздуть представление после создания диалогового windows.

Ниже приведен код из руководства Google, поэтому ответ заключается в том, что вы не могли бы сделать так, как ваш в onCreateDialog (), вы должны использовать super.onCreateDialog (), чтобы получить диалог.

 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; } } 

Вот пример использования findViewById в fragmentе диалога

 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(); } 

Как говорит @Xavier Egea, если у вас есть как onCreateView (), так и onCreateDialog (), вы рискуете получить запрос requestFeature () перед добавлением содержимого «сбой». Это потому, что BOTH onCreateDialog (), а затем onCreateView () вызывается, когда вы показываете () этот fragment как диалог (почему, я не знаю). Как упоминал Трэвис Кристиан, inflate () в onCreateView () после того, как диалог был создан в onCreateDialog (), является причиной сбоя.

Один из способов реализовать обе эти функции, но избежать этого сбоя: используйте getShowsDialog (), чтобы ограничить выполнение вашего onCreateView () (так что ваш inflate () не вызывается). Таким образом, только ваш код onCreateDialog () выполняется, когда вы показываете диалог DialogFragment как диалог, но ваш код onCreateView () может вызываться, когда ваш DialogFragment используется как fragment в макете.

 // 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; } 

Если вы хотите легко получить доступ к свойствам диалога, например заголовку и кнопке увольнения, но вы также хотите использовать свой собственный макет, вы можете использовать LayoutInflator с вашим Builder, когда вы переопределяете onCreateDialog.

 @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(); } 
  • eclipse с Android sdk, ERROR: пространство кучи Java
  • Получите силу сигнала Bluetooth
  • Доступ к мультимедийному streamу Android для аудиовизуализации
  • Java Runtime.exec ()
  • Передача массивов с помощью Intent.putExtra
  • Как просмотреть файл Realm в браузере Realm?
  • Android java.lang.NoClassDefFoundError: org.jsoup.Jsoup
  • API Карт Google и настраиваемый маршрут полилинии между маркерами
  • Импортирование двух classов с одинаковым именем. Как обращаться?
  • Как разрешить «Дублировать файлы, скопированные в APK META-INF / *»,
  • Как преобразовать слова в число?
  • Давайте будем гением компьютера.