java - style - dialogfragment with edittext
DiseƱo personalizado para DialogFragment OnCreateView vs. OnCreateDialog (6)
Este primer enfoque funciona para mí ... hasta que quiera usar FindViewByID.
Supongo que no está findViewById()
en la vista devuelta por inflate()
, intente esto:
View view = i.inflate(Resource.Layout.frag_SelectCase, null);
// Now use view.findViewById() to do what you want
b.setView(view);
return b.create();
Intento crear un DialogFragment usando mi propio Layout.
He visto un par de enfoques diferentes. A veces, el diseño se establece en OnCreateDialog de la siguiente manera: (Estoy usando Mono pero me he acostumbrado un poco a 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();
}
Este primer enfoque funciona para mí ... hasta que quiera usar findViewByID.
así que después de un poco de google probé el segundo enfoque que implica anular OnCreateView
Así que comenté dos líneas de OnCreateDialog
que configuraron el diseño y luego agregué esto:
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;
}
lo que me da un error encantador:
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
Estoy perplejo.
A continuación, el código proviene de la guía de Google, por lo que la respuesta es que no podría hacer lo mismo que el suyo en onCreateDialog (), debe usar super.onCreateDialog () para obtener un cuadro de diálogo.
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;
}
}
Aquí hay un ejemplo de cómo usar findViewById en un Fragmento de diálogo
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();
}
Como dice @Xavier Egea, si tiene ambos onCreateView () y onCreateDialog () implementados, se corre el riesgo de que se produzca el bloqueo "requestFeature () se debe llamar antes de agregar contenido". Esto se debe a que se llama a ambos onCreateDialog () y luego a onCreateView () cuando se muestra () ese fragmento como un cuadro de diálogo (por qué, no lo sé). Como mencionó Travis Christian, el inflado () en onCreateView () después de que se creó un diálogo en onCreateDialog () es lo que causa el bloqueo.
Una forma de implementar estas dos funciones, pero evite este bloqueo: use getShowsDialog () para limitar la ejecución de su onCreateView () (por lo tanto, no se llama a su inflate ()). De esta forma, solo su código onCreateDialog () se ejecuta cuando se muestra DialogFragment como un diálogo, pero se puede invocar su código onCreateView () cuando su DialogFragment se utiliza como un fragmento en un diseño.
// 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;
}
Si desea tener fácil acceso a las propiedades del diálogo, como el título y el botón de descartar, pero también desea usar su propio diseño, puede usar un LayoutInflator con su Constructor al anular en Crear un registro.
@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();
}
Tuve la misma excepción con el siguiente código:
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;
}
}
Debe elegir anular solo uno de onCreateView o onCreateDialog en un DialogFragment. La anulación de ambos dará como resultado la excepción: "requestFeature () debe llamarse antes de agregar contenido".
Importante
Para una respuesta completa, consulte el comentario de @TravisChristian. Como dijo, puede anular ambos, pero el problema surge cuando intenta inflar la vista después de haber creado la vista de diálogo.