studio - input dialog android
Cómo implementar una vista AlertDialog personalizada (11)
Custom AlertDialog
Este ejemplo completo incluye pasar datos a la Actividad.
Crea un diseño personalizado
En este sencillo ejemplo, se utiliza un diseño con EditText
, pero puede reemplazarlo con lo que desee.
custom_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:paddingLeft="20dp"
android:paddingRight="20dp"
android:layout_width="match_parent"
android:layout_height="match_parent">
<EditText
android:id="@+id/editText"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
Usa el diálogo en el código
Las partes clave son
- usando
setView
para asignar el diseño personalizado aAlertDialog.Builder
- enviando datos a la actividad cuando se hace clic en un botón de diálogo.
Este es el código completo del proyecto de ejemplo que se muestra en la imagen de arriba:
MainActivity.java
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void showAlertDialogButtonClicked(View view) {
// create an alert builder
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Name");
// set the custom layout
final View customLayout = getLayoutInflater().inflate(R.layout.custom_layout, null);
builder.setView(customLayout);
// add a button
builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// send data from the AlertDialog to the Activity
EditText editText = customLayout.findViewById(R.id.editText);
sendDialogDataToActivity(editText.getText().toString());
}
});
// create and show the alert dialog
AlertDialog dialog = builder.create();
dialog.show();
}
// do something with the data coming from the AlertDialog
private void sendDialogDataToActivity(String data) {
Toast.makeText(this, data, Toast.LENGTH_SHORT).show();
}
}
Notas
- Si te encuentras usando esto en varios lugares, entonces considera hacer una subclase
DialogFragment
como se describe en la documentation .
Ver también
- Diálogo de alerta de Android con uno, dos y tres botones
- ¿Cómo puedo mostrar una vista de lista en un Diálogo de alerta de Android?
En los documentos de Android en AlertDialog , proporciona las siguientes instrucciones y ejemplos para configurar una vista personalizada en AlertDialog:
Si desea visualizar una vista más compleja, busque FrameLayout llamado "cuerpo" y agregue su vista a él:
FrameLayout fl = (FrameLayout) findViewById(R.id.body);
fl.add(myView, new LayoutParams(FILL_PARENT, WRAP_CONTENT));
En primer lugar, es bastante obvio que add()
es un error tipográfico y está destinado a ser addView()
.
Estoy confundido con la primera línea usando R.id.body. Parece que es el elemento del cuerpo de AlertDialog ... pero no puedo ingresar eso en mi código b / c sino que da un error de compilación. ¿Dónde se define o asigna R.id.body o lo que sea?
Aquí está mi código. Intenté usar setView(findViewById(R.layout.whatever)
en el generador, pero no funcionó. ¿Lo asumo porque no lo he inflado manualmente?
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Title")
.setCancelable(false)
.setPositiveButton("Go", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int id) {
EditText textBox = (EditText) findViewById(R.id.textbox);
doStuff();
}
});
FrameLayout f1 = (FrameLayout)findViewById(R.id.body /*CURRENTLY an ERROR*/);
f1.addView(findViewById(R.layout.dialog_view));
AlertDialog alert = builder.create();
alert.show();
AlertDialog.setView (View view) agrega la vista dada a R.id. FrameLayout personalizado . El siguiente es un fragmento del código fuente de Android de AlertController.setupView () que finalmente maneja esto (mView es la vista dada al método AlertDialog.setView).
...
FrameLayout custom = (FrameLayout) mWindow.findViewById(R.id.**custom**);
custom.addView(**mView**, new LayoutParams(FILL_PARENT, FILL_PARENT));
...
Después de cambiar el ID itroid.R.id.custom, necesitaba agregar lo siguiente para mostrar la Vista:
((View) f1.getParent()).setVisibility(View.VISIBLE);
Sin embargo, esto hizo que la nueva Vista se procesara en una gran vista principal sin fondo, rompiendo el cuadro de diálogo en dos partes (texto y botones, con la nueva Vista entre ellos). Finalmente obtuve el efecto que quería insertando mi vista al lado del mensaje:
LinearLayout f1 = (LinearLayout)findViewById(android.R.id.message).getParent().getParent();
Encontré esta solución explorando el árbol de View con View.getParent () y View.getChildAt (int). Sin embargo, no estoy muy feliz con ninguno de los dos. Nada de esto está en los documentos de Android y si alguna vez cambian la estructura de AlertDialog, esto podría romperse.
Estás en lo correcto, es porque no lo inflaste manualmente. Parece que estás tratando de "extraer" la ID de "cuerpo" del diseño de tu Actividad, y eso no funcionará.
Probablemente quieras algo como esto:
LayoutInflater inflater = getLayoutInflater();
FrameLayout f1 = (FrameLayout)alert.findViewById(android.R.id.body);
f1.addView(inflater.inflate(R.layout.dialog_view, f1, false));
Esto funcionó para mí:
dialog.setView(dialog.getLayoutInflater().inflate(R.layout.custom_dialog_layout, null));
La forma más sencilla de hacerlo es mediante el uso de android.support.v7.app.AlertDialog
lugar de android.app.AlertDialog
donde se puede usar el public AlertDialog.Builder setView (int layoutResId)
debajo de API 21.
new AlertDialog.Builder(getActivity())
.setTitle(title)
.setView(R.layout.dialog_basic)
.setPositiveButton(android.R.string.ok,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
//Do something
}
}
)
.setNegativeButton(android.R.string.cancel,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
//Do something
}
}
)
.create();
Las líneas de código más simples que funcionan para mí son las siguientes:
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setView(R.layout.layout_resource_id);
builder.show();
Cualquiera que sea el tipo de diseño (LinearLayout, FrameLayout, RelativeLayout) funcionará por setView
y solo diferirá en la apariencia y el comportamiento.
Los documentos de Android han sido editados para corregir los errores.
La vista dentro de AlertDialog se llama android.R.id.custom
http://developer.android.com/reference/android/app/AlertDialog.html
Puede crear su vista directamente desde Layout Inflater, solo necesita usar el nombre de su archivo XML de diseño y el ID del diseño en el archivo.
Su archivo XML debe tener una ID como esta:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/dialog_layout_root"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:padding="10dp"
/>
Y luego puede configurar su diseño en el generador con el siguiente código:
LayoutInflater inflater = getLayoutInflater();
View dialoglayout = inflater.inflate(R.layout.dialog_layout, null);
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setView(dialoglayout);
builder.show();
Tendría más sentido hacerlo de esta manera, con la menor cantidad de código.
new AlertDialog.Builder(this).builder(this)
.setTitle("Title")
.setView(R.id.dialog_view) //notice this setView was added
.setCancelable(false)
.setPositiveButton("Go", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int id) {
EditText textBox = (EditText) findViewById(R.id.textbox);
doStuff();
}
}).show();
Para obtener una lista ampliada de cosas que puede establecer, comience a escribir .set
en Android Studio
android.R.id.custom estaba volviendo nulo para mí. Logré hacer que esto funcione en caso de que alguien se encuentre con el mismo problema,
AlertDialog.Builder builder = new AlertDialog.Builder(context)
.setTitle("My title")
.setMessage("Enter password");
final FrameLayout frameView = new FrameLayout(context);
builder.setView(frameView);
final AlertDialog alertDialog = builder.create();
LayoutInflater inflater = alertDialog.getLayoutInflater();
View dialoglayout = inflater.inflate(R.layout.simple_password, frameView);
alertDialog.show();
Como referencia, R.layout.simple_password es:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<EditText
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="@+id/password_edit_view"
android:inputType="textPassword"/>
<CheckBox
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/show_password"
android:id="@+id/show_password_checkbox"
android:layout_gravity="left|center_vertical"
android:checked="false"/>
</LinearLayout>