Join FlipAndroid.COM Telegram Group: https://t.me/joinchat/F_aqThGkhwcLzmI49vKAiw


Problema al inflar la vista personalizada de AlertDialog en DialogFragment

Estoy intentando crear un DialogFragment usando una visión de encargo en un AlertDialog . Esta vista se debe inflar de xml. En mi clase DialogFragment tengo:

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

He intentado otros métodos de inflación para .setView() tales como:

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

y

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

Después de establecer el fragmento de destino en el fragmento que muestra este diálogo.

Todos estos intentos de inflar mi resultado de vista personalizada en la siguiente excepción:

 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) 

Mientras que si intento utilizar el DialogFragment del getLayoutInflator(Bundle) como esto:

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

StackOverflowError un StackOverflowError .

¿Alguien sabe cómo inflar una vista personalizada para un AlertDialog en un DialogFragment ?

9 Solutions collect form web for “Problema al inflar la vista personalizada de AlertDialog en DialogFragment”

La primera línea de error me da la pista de que esto está relacionado con cómo está creando su diálogo – no el diálogo en sí.

¿Está creando el cuadro de diálogo automáticamente (lo que podría significar que se llama antes de que las vistas estén configuradas) o en respuesta a un clic de botón? Inicialmente tuve problemas con fragmentos debido al orden de instancia.

Utilicé el mismo código para fijar la opinión como usted tiene, y mi resultado trabaja. He cortado la otra configuración para hacer este aspecto más limpio, pero funciona con o sin ella.

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

Estoy sorprendido por estas respuestas, ya que ninguna de ellas soluciona el problema.

Un DialogFragment le permite reutilizar la misma interfaz de usuario para un diálogo e integrado en su aplicación en otro lugar como un fragmento. Una característica muy útil. Según la documentación de google, puede lograr esto mediante la sustitución onCreateDialog y onCreateView. http://developer.android.com/reference/android/app/DialogFragment.html

Hay tres escenarios aquí:

  1. Anulación onCreateDialog solamente – Funciona como un diálogo pero no se puede integrar en otro lugar.
  2. Anulación onCreateView solamente – No funciona como un diálogo pero puede ser integrado en otro lugar.
  3. Anular ambos – Funciona como un diálogo y puede ser integrado en otro lugar.

Solución: La clase AlertDialog está llamando a otra clase que llama requestFeature. Para solucionar esto .. No utilice el AlertDialog, en lugar de usar un cuadro de diálogo normal o lo que super.onCreateDialog devuelve. Esta es la solución que he encontrado que funciona mejor.

Advertencia: Otros diálogos como DatePickerDialog, ProgressDialog, TimePickerDialog heredan de AlertDialog y probablemente causarán el mismo error.

Bottom Line: DialogFragment es bueno si necesita crear una interfaz muy personalizada que necesita ser utilizado en varios lugares. No parece funcionar para reutilizar los cuadros de diálogo android existentes.

Evite el bloqueo de la función de solicitud y utilice el mismo diseño:

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

Yo tuve el mismo problema. En mi caso, fue debido a que Android Studio creó una plantilla onCreateView que volvió a inflar una nueva vista en lugar de devolver la vista creada en onCreateDialog. OnCreateView se llama después de onCreateDialog, por lo que la solución era simplemente reurnt la vista fragmentos.

 @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { return this.getView(); } 

Frente a la misma cuestión, y tomó mucho tiempo para deshacerse del error. Finalmente pasar el identificador de recursos al método setView () resolvió el problema. Añada la vista de conjunto como a continuación:

.setView(R.layout.dialog)

En el código en el que llama

  create(). 

Remplazar con

 show(). 

No he inflado de XML pero he hecho la generación dinámica de la opinión en un DialogFragment con éxito:

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

Lo que desea hacer en su lugar es crear su vista personalizada en el método onCreateView como lo haría normalmente. Si quieres hacer algo como cambiar el título del diálogo, lo haces en onCreateView.

He aquí un ejemplo para ilustrar lo que quiero decir:

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

Entonces simplemente llame a:

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

Y voila, un diálogo con su propia vista personalizada.

Como necesitaba mucho tiempo para resolver el mismo problema (Pop hasta un simple texto de diálogo), decidí compartir mi solución:

El fichero de diseño connectivity_dialog.xml contiene un TextView simple con el texto del mensaje:

 <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="center" android:layout_gravity="center"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginStart="20dp" android:layout_marginEnd="20dp" android:layout_marginTop="20dp" android:layout_marginBottom="20dp" android:text="Connectivity was lost" android:textSize="34sp" android:gravity="center" /> </RelativeLayout> 

La Actividad que muestra el "diálogo" implementa una clase interna (como DialogFragment es un Fragmento y no un Diálogo; más información, consulte https://stackoverflow.com/a/5607560/6355541 ). La actividad puede activar y desactivar DialogFragment a través de dos funciones. Si está utilizando android.support.v4, puede cambiar a getSupportFragmentManager ():

 public static class ConnDialogFragment extends DialogFragment { public static ConnDialogFragment newInstance() { ConnDialogFragment cdf = new ConnDialogFragment(); cdf.setRetainInstance(true); cdf.setCancelable(false); return cdf; } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { return inflater.inflate(R.layout.connectivity, container, false); } } private void dismissConn() { DialogFragment df = (DialogFragment) getFragmentManager().findFragmentByTag("conn"); if (df != null) df.dismiss(); } private void showConn() { FragmentTransaction ft = getFragmentManager().beginTransaction(); Fragment prev = getFragmentManager().findFragmentByTag("conn"); if (prev != null) ft.remove(prev); ft.addToBackStack(null); ConnDialogFragment cdf = ConnDialogFragment.newInstance(); cdf.show(ft, "conn"); } 
FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.