¿Cómo puedo mostrar una vista de lista en un cuadro de diálogo de alerta de Android?

291

En una aplicación de Android, quiero mostrar una vista de lista personalizada en un AlertDialog.

¿Cómo puedo hacer esto?

Brad Larson
fuente
Simplemente tome la Lista de cadenas, luego cree la secuencia de CharSequence [], luego use AlertDialog.Builder para mostrar los elementos. Aquí está el ejemplo más simple con la instantánea feelzdroid.com/2014/12/…
Naruto

Respuestas:

498

Se usa debajo del código para mostrar una lista personalizada en AlertDialog

AlertDialog.Builder builderSingle = new AlertDialog.Builder(DialogActivity.this);
builderSingle.setIcon(R.drawable.ic_launcher);
builderSingle.setTitle("Select One Name:-");

final ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(DialogActivity.this, android.R.layout.select_dialog_singlechoice);
arrayAdapter.add("Hardik");
arrayAdapter.add("Archit");
arrayAdapter.add("Jignesh");
arrayAdapter.add("Umang");
arrayAdapter.add("Gatti");

builderSingle.setNegativeButton("cancel", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                dialog.dismiss();
            }
        });

builderSingle.setAdapter(arrayAdapter, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                String strName = arrayAdapter.getItem(which);
                AlertDialog.Builder builderInner = new AlertDialog.Builder(DialogActivity.this);
                builderInner.setMessage(strName);
                builderInner.setTitle("Your Selected Item is");
                builderInner.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog,int which) {
                                dialog.dismiss();
                            }
                        });
                builderInner.show();
            }
        });
builderSingle.show();
karan singh rajpoot
fuente
¿Hay alguna posibilidad de detectar clics largos en estos elementos? Estoy buscando horas para una solución de menú emergente que funciona en todos los niveles de API
wutzebaer
77
@Shvet supuestamente, show () crea y muestra el diálogo, mientras que create () solo lo crea.
htafoya
¿Cómo puedo usar esta configuración, pero en lugar de codificar mi lista, necesito obtener algunos datos del análisis que el usuario ya tiene?
Stanley Santos
@stanleysantoso cree su propio adaptador, llénelo con datos y luego configúrelo como el adaptador para el diálogo de alerta: dialogBuilder.setAdapter (MyCustomAdapter); Eso debería funcionar
CantThinkOfAnything
1
¿Cuál es el diseño select_dialog_single_choice?
ForceFieldsForDoors
254

De acuerdo con la documentación , hay tres tipos de listas que se pueden usar con AlertDialog:

  1. Lista tradicional de opción única
  2. Lista persistente de opción única (botones de opción)
  3. Lista persistente de opción múltiple (casillas de verificación)

Daré un ejemplo de cada uno a continuación.

Lista tradicional de opción única

La forma de hacer una lista tradicional de opción única es utilizarla setItems.

ingrese la descripción de la imagen aquí

Versión Java

// setup the alert builder
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setTitle("Choose an animal");

// add a list
String[] animals = {"horse", "cow", "camel", "sheep", "goat"};
builder.setItems(animals, new DialogInterface.OnClickListener() {
    @Override
    public void onClick(DialogInterface dialog, int which) {
        switch (which) {
            case 0: // horse
            case 1: // cow
            case 2: // camel
            case 3: // sheep
            case 4: // goat
        }
    }
});

// create and show the alert dialog
AlertDialog dialog = builder.create();
dialog.show();

No hay necesidad de un botón Aceptar porque tan pronto como el usuario hace clic en un elemento de la lista, el control vuelve a OnClickListener.

Versión Kotlin

// setup the alert builder
val builder = AlertDialog.Builder(context)
builder.setTitle("Choose an animal")

// add a list
val animals = arrayOf("horse", "cow", "camel", "sheep", "goat")
builder.setItems(animals) { dialog, which ->
    when (which) {
        0 -> { /* horse */ }
        1 -> { /* cow   */ }
        2 -> { /* camel */ }
        3 -> { /* sheep */ }
        4 -> { /* goat  */ }
    }
}

// create and show the alert dialog
val dialog = builder.create()
dialog.show()

Lista de botones de radio

ingrese la descripción de la imagen aquí

La ventaja de la lista de botones de radio sobre la lista tradicional es que el usuario puede ver cuál es la configuración actual. La forma de hacer una lista de botones de radio es usarla setSingleChoiceItems.

Versión Java

// setup the alert builder
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setTitle("Choose an animal");

// add a radio button list
String[] animals = {"horse", "cow", "camel", "sheep", "goat"};
int checkedItem = 1; // cow
builder.setSingleChoiceItems(animals, checkedItem, new DialogInterface.OnClickListener() {
    @Override
    public void onClick(DialogInterface dialog, int which) {
        // user checked an item
    }
});

// add OK and Cancel buttons
builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
    @Override
    public void onClick(DialogInterface dialog, int which) {
        // user clicked OK
    }
});
builder.setNegativeButton("Cancel", null);

// create and show the alert dialog
AlertDialog dialog = builder.create();
dialog.show();

Codifiqué el elemento elegido aquí, pero puedes seguirlo con una variable de miembro de clase en un proyecto real.

Versión Kotlin

// setup the alert builder
val builder = AlertDialog.Builder(context)
builder.setTitle("Choose an animal")

// add a radio button list
val animals = arrayOf("horse", "cow", "camel", "sheep", "goat")
val checkedItem = 1 // cow
builder.setSingleChoiceItems(animals, checkedItem) { dialog, which ->
    // user checked an item
}


// add OK and Cancel buttons
builder.setPositiveButton("OK") { dialog, which ->
    // user clicked OK
}
builder.setNegativeButton("Cancel", null)

// create and show the alert dialog
val dialog = builder.create()
dialog.show()

Lista de casillas de verificación

ingrese la descripción de la imagen aquí

La forma de hacer una lista de casillas de verificación es utilizarla setMultiChoiceItems.

Versión Java

// setup the alert builder
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setTitle("Choose some animals");

// add a checkbox list
String[] animals = {"horse", "cow", "camel", "sheep", "goat"};
boolean[] checkedItems = {true, false, false, true, false};
builder.setMultiChoiceItems(animals, checkedItems, new DialogInterface.OnMultiChoiceClickListener() {
    @Override
    public void onClick(DialogInterface dialog, int which, boolean isChecked) {
        // user checked or unchecked a box
    }
});

// add OK and Cancel buttons
builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
    @Override
    public void onClick(DialogInterface dialog, int which) {
        // user clicked OK
    }
});
builder.setNegativeButton("Cancel", null);

// create and show the alert dialog
AlertDialog dialog = builder.create();
dialog.show();

Aquí codifiqué los elementos de la lista que ya estaban marcados. Es más probable que desee realizar un seguimiento de ellos en un ArrayList<Integer>. Vea el ejemplo de documentación para más detalles. También puede configurar los elementos marcados nullsi siempre desea que todo comience sin marcar.

Versión Kotlin

// setup the alert builder
val builder = AlertDialog.Builder(context)
builder.setTitle("Choose some animals")

// add a checkbox list
val animals = arrayOf("horse", "cow", "camel", "sheep", "goat")
val checkedItems = booleanArrayOf(true, false, false, true, false)
builder.setMultiChoiceItems(animals, checkedItems) { dialog, which, isChecked ->
    // user checked or unchecked a box
}

// add OK and Cancel buttons
builder.setPositiveButton("OK") { dialog, which ->
    // user clicked OK
}
builder.setNegativeButton("Cancel", null)

// create and show the alert dialog
val dialog = builder.create()
dialog.show()

Notas

  • Para el contextcódigo anterior, no lo use getApplicationContext()o obtendrá un IllegalStateException(vea aquí por qué). En su lugar, obtenga una referencia al contexto de actividad, como con this.
  • También puede rellenar los elementos de la lista de una base de datos u otra fuente utilizando setAdaptero setCursoro pasar en una Cursoro ListAdapteren el setSingleChoiceItemso setMultiChoiceItems.
  • Si la lista es más larga de lo que cabe en la pantalla, entonces el diálogo la desplazará automáticamente. Sin embargo, si tiene una lista realmente larga, supongo que probablemente debería hacer un diálogo personalizado con un RecyclerView .
  • Para probar todos los ejemplos anteriores, solo tuve un proyecto simple con un solo botón que mostró el cuadro de diálogo al hacer clic:

    import android.support.v7.app.AppCompatActivity;
    
    public class MainActivity extends AppCompatActivity {
    
        Context context;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            context = this;
        }
    
        public void showAlertDialogButtonClicked(View view) {
    
            // example code to create alert dialog lists goes here
        }
    }

Relacionado

Suragch
fuente
2
Esto es genial, ahora agregue íconos;)
AaA
1
@AaA, creo que necesitaría crear un cuadro de diálogo de alerta de diseño personalizado que use un RecyclerViewen el diseño para eso.
Suragch
¿Qué significa el 'qué' en el método de diálogo onclick?
idophishing
@gonephishing, según la documentación , es "el botón en el que se hizo clic (ej. BUTTON_POSITIVE) o la posición del elemento en el que se hizo clic".
Suragch
1
Si desea implementar una lista simple (1) con un adaptador personalizado, use Builder.setAdapter(ListAdapter, DialogInterface.OnClickListener): whichin listener's onClickserá igual a la posición del elemento seleccionado. Builder.setOnItemSelectedListenerno tendrá efecto
Miha_x64
122

Puedes usar un diálogo personalizado.

Diseño de diálogo personalizado. list.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="wrap_content"
    android:layout_height="wrap_content">
    <ListView
        android:id="@+id/lv"
        android:layout_width="wrap_content"
        android:layout_height="fill_parent"/>
</LinearLayout>

En su actividad

Dialog dialog = new Dialog(Activity.this);
       dialog.setContentView(R.layout.list)

ListView lv = (ListView ) dialog.findViewById(R.id.lv);
dialog.setCancelable(true);
dialog.setTitle("ListView");
dialog.show();

Editar:

Usando alertdialog

String names[] ={"A","B","C","D"};
AlertDialog.Builder alertDialog = new AlertDialog.Builder(MainActivity.this);
LayoutInflater inflater = getLayoutInflater();
View convertView = (View) inflater.inflate(R.layout.custom, null);
alertDialog.setView(convertView);
alertDialog.setTitle("List");
ListView lv = (ListView) convertView.findViewById(R.id.lv);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,names);
lv.setAdapter(adapter);
alertDialog.show();

custom.xml

<?xml version="1.0" encoding="utf-8"?>
<ListView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/listView1"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" >

</ListView>

Chasquido

ingrese la descripción de la imagen aquí

Raghunandan
fuente
1
@Juan - devtopia.coop editaste mi publicación después de votar solo para votar a favor. ¿Podría comentar qué está mal
Raghunandan
Nada con la versión actual, la anterior carecía de todo el adaptador y, por lo tanto, solo mostraba un ListView vacío, con mucho gusto elimino mi voto negativo ahora. He votado una respuesta incompleta, no en esta edición de hace 3 horas.
Juan Cortés
@Raghunandan, usé su código pero obtuve una excepción en lv.setAdapter (adaptador); línea, me puedes ayudar?
Ahmad Vatani
@ Ahmad, ¿cuál es la excitación?
Raghunandan
1
@NeilGaliaskarov sí, es desplazable. Listview se desplazará
Raghunandan
44
final CharSequence[] items = {"A", "B", "C"};

AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Make your selection");
builder.setItems(items, new DialogInterface.OnClickListener() {
    public void onClick(DialogInterface dialog, int item) {
        // Do something with the selection
        mDoneButton.setText(items[item]);
    }
});
AlertDialog alert = builder.create();
alert.show();
Arhat Baid
fuente
1
¿Qué es m.DoneButton?
ForceFieldsForDoors
2
@ArhatBaid Pero setItems no funciona cuando pongo un mensaje en setMessage. Busqué en google pero la respuesta que encontré fue configurar el mensaje en setTitle. Pero el problema es setTitle solo permite pocos caracteres. ¿Hay alguna manera de usar setMessage y setItems en el cuadro de diálogo de alerta?
David
@David para eso tienes que ir a un diálogo personalizado.
Arhat Baid
1
Esta solución es muy buena porque también puede ir con un ListAdaptercon setSingleChoiceItems(muy similar a la llamada anterior)
snotyak
Perfecto como se esperaba ... maneja cientos de artículos con un código mínimo. :)
jeet.chanchawat
10

Use la import android.app.AlertDialog;importación " " y luego escriba

    String[] items = {"...","...."};             
    AlertDialog.Builder build = new AlertDialog.Builder(context);
    build.setItems(items, new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int which) {
            //do stuff....
        }
    }).create().show();
Facebamm
fuente
necesitabas bc con create, construyes el AlertDialog y luego lo muestras. No el constructor. (c) Facebamm
Facebamm
@Facebamm eso no es cierto. show()hace las dos cosas. Calling this method is functionally identical to: AlertDialog dialog = builder.create(); dialog.show();eso es directamente de la show()documentación del método
ᴛʜᴇᴘᴀᴛᴇʟ
es correcto, pero a veces tengo algunos errores visibles en las interfaces de usuario. (c) Facebamm
Facebamm
No, eso no es verdad. show () es idéntico a create (). show (); / ** * Crea un {@link AlertDialog} con los argumentos proporcionados a este * constructor e inmediatamente muestra el diálogo. * <p> * Llamar a este método es funcionalmente idéntico a: * <pre> * AlertDialog dialog = builder.create (); * dialog.show (); * </pre> * / public AlertDialog show () {final AlertDialog dialog = create (); dialog.show (); diálogo de retorno; }
Emanuel S
ok, lo he probado por un tiempo y digo sry, eso es cierto. (c) Facebamm
Facebamm
4

Esto es demasiado simple

final CharSequence[] items = {"Take Photo", "Choose from Library", "Cancel"};

AlertDialog.Builder builder = new AlertDialog.Builder(MyProfile.this);

builder.setTitle("Add Photo!");
builder.setItems(items, new DialogInterface.OnClickListener() {
    @Override
    public void onClick(DialogInterface dialog, int item) {
        if (items[item].equals("Take Photo")) {
            getCapturesProfilePicFromCamera();
        } else if (items[item].equals("Choose from Library")) {
            getProfilePicFromGallery();
        } else if (items[item].equals("Cancel")) {
            dialog.dismiss();
        }
    }
});
builder.show();
Jaydeep purohit
fuente
3

Como principiante, le sugiero que visite http://www.mkyong.com/android/android-custom-dialog-example/

Voy a resumir lo que básicamente hace

  1. Crea un archivo XML para el diálogo y la actividad principal.
  2. En la actividad principal en el lugar requerido crea un objeto de clase android Dialog
  3. Agrega estilo personalizado y texto basado en el archivo XML
  4. Llama al dialog.show()método.
cjds
fuente
1

En Kotlin:

fun showListDialog(context: Context){
    // setup alert builder
    val builder = AlertDialog.Builder(context)
    builder.setTitle("Choose an Item")

    // add list items
    val listItems = arrayOf("Item 0","Item 1","Item 2")
    builder.setItems(listItems) { dialog, which ->
        when (which) {
            0 ->{
                Toast.makeText(context,"You Clicked Item 0",Toast.LENGTH_LONG).show()
                dialog.dismiss()
            }
            1->{
                Toast.makeText(context,"You Clicked Item 1",Toast.LENGTH_LONG).show()
                dialog.dismiss()
            }
            2->{
                Toast.makeText(context,"You Clicked Item 2",Toast.LENGTH_LONG).show()
                dialog.dismiss()
            }
        }
    }

    // create & show alert dialog
    val dialog = builder.create()
    dialog.show()
}
Varsha Prabhakar
fuente
1
Agregue alguna descripción a su respuesta.
Mathews Sunny el
1
¿Qué tipo de descripción?
Varsha Prabhakar
1

Así es como se muestra el cuadro de diálogo de diseño personalizado con un elemento de lista personalizado, se puede personalizar según sus necesidades.

ingrese la descripción de la imagen aquí

PASO - 1 Cree el diseño de DialogBox, es decir: -

R.layout.assignment_dialog_list_view

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/rectangle_round_corner_assignment_alert"
    android:orientation="vertical">
    <TextView
        android:id="@+id/tv_popup_title"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginBottom="8dp"
        android:singleLine="true"
        android:paddingStart="4dp"
        android:text="View as:"
        android:textColor="#4f4f4f" />

    <ListView
        android:id="@+id/lv_assignment_users"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1" />
</LinearLayout>

PASO - 2 Cree un diseño de elemento de lista personalizado según su lógica empresarial

R.layout.item_assignment_dialog_list_layout

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:gravity="center"
    android:padding="4dp"
    android:orientation="horizontal">
    <ImageView
        android:id="@+id/iv_user_profile_image"
        android:visibility="visible"
        android:layout_width="42dp"
        android:layout_height="42dp" />
    <TextView
        android:id="@+id/tv_user_name"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:paddingTop="8dp"
        android:layout_marginStart="8dp"
        android:paddingBottom="8dp"
        android:textColor="#666666"
        android:textSize="18sp"
        tools:text="ABCD XYZ" />
</LinearLayout>

PASO - 3 Cree una clase de modelo de datos de su elección

public class AssignmentUserModel {

private String userId;
private String userName;
private String userRole;
private Bitmap userProfileBitmap;

public AssignmentUserModel(String userId, String userName, String userRole, Bitmap userProfileBitmap) {
    this.userId = userId;
    this.userName = userName;
    this.userRole = userRole;
    this.userProfileBitmap = userProfileBitmap;
}


public String getUserId() {
    return userId;
}

public void setUserId(String userId) {
    this.userId = userId;
}

public String getUserName() {
    return userName;
}

public void setUserName(String userName) {
    this.userName = userName;
}

public String getUserRole() {
    return userRole;
}

public void setUserRole(String userRole) {
    this.userRole = userRole;
}

public Bitmap getUserProfileBitmap() {
    return userProfileBitmap;
}

public void setUserProfileBitmap(Bitmap userProfileBitmap) {
    this.userProfileBitmap = userProfileBitmap;
}

}

PASO - 4 Crear adaptador personalizado

public class UserListAdapter extends ArrayAdapter<AssignmentUserModel> {
private final Context context;
private final List<AssignmentUserModel> userList;

public UserListAdapter(@NonNull Context context, int resource, @NonNull List<AssignmentUserModel> objects) {
    super(context, resource, objects);
    userList = objects;
    this.context = context;
 }

@SuppressLint("ViewHolder")
@NonNull
@Override
public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
    LayoutInflater inflater = (LayoutInflater) context
            .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    View rowView = inflater.inflate(R.layout.item_assignment_dialog_list_layout, parent, false);
    ImageView profilePic = rowView.findViewById(R.id.iv_user_profile_image);
    TextView userName = rowView.findViewById(R.id.tv_user_name);
    AssignmentUserModel user = userList.get(position);

    userName.setText(user.getUserName());

    Bitmap bitmap = user.getUserProfileBitmap();

    profilePic.setImageDrawable(bitmap);

    return rowView;
}

}

PASO - 5 Cree esta función y proporcione ArrayList del modelo de datos anterior en este método

// Pass list of your model as arraylist
private void showCustomAlertDialogBoxForUserList(ArrayList<AssignmentUserModel> allUsersList) {
        final Dialog dialog = new Dialog(mActivity);
        dialog.setContentView(R.layout.assignment_dialog_list_view);
        if (dialog.getWindow() != null) {
            dialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT)); // this is optional
        }
        ListView listView = dialog.findViewById(R.id.lv_assignment_users);
        TextView tv = dialog.findViewById(R.id.tv_popup_title);
        ArrayAdapter arrayAdapter = new UserListAdapter(context, R.layout.item_assignment_dialog_list_layout, allUsersList);
        listView.setAdapter(arrayAdapter);
        listView.setOnItemClickListener((adapterView, view, which, l) -> {
            Log.d(TAG, "showAssignmentsList: " + allUsersList.get(which).getUserId());
           // TODO : Listen to click callbacks at the position
        });
        dialog.show();
    }

Paso - 6 Dar fondo de esquina redonda al cuadro de diálogo

@ drawable / rectangle_round_corner_assignment_alert

    <?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <solid android:color="#ffffffff" />
    <corners android:radius="16dp" />
    <padding
        android:bottom="16dp"
        android:left="16dp"
        android:right="16dp"
        android:top="16dp" />
</shape>
Divyanshu Kumar
fuente
0

¿No es más fácil hacer que se invoque un método después de la creación de la unidad EditText en un AlertDialog, para uso general?

public static void EditTextListPicker(final Activity activity, final EditText EditTextItem, final String SelectTitle, final String[] SelectList) {
    EditTextItem.setOnLongClickListener(new View.OnLongClickListener() {
        @Override
        public boolean onLongClick(View v) {
            AlertDialog.Builder builder = new AlertDialog.Builder(activity);
            builder.setTitle(SelectTitle);
            builder.setItems(SelectList, new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialogInterface, int item) {
                    EditTextItem.setText(SelectList[item]);
                }
            });
            builder.create().show();
            return false;
        }
    });
}
Jan Bergström
fuente
0
private void AlertDialogue(final List<Animals> animals) {
 final AlertDialog.Builder alertDialog = new AlertDialog.Builder(AdminActivity.this);
 alertDialog.setTitle("Filter by tag");

 final String[] animalsArray = new String[animals.size()];

 for (int i = 0; i < tags.size(); i++) {
  animalsArray[i] = tags.get(i).getanimal();

 }

 final int checkedItem = 0;
 alertDialog.setSingleChoiceItems(animalsArray, checkedItem, new DialogInterface.OnClickListener() {
  @Override
  public void onClick(DialogInterface dialog, int which) {

   Log.e(TAG, "onClick: " + animalsArray[which]);

  }
 });


 AlertDialog alert = alertDialog.create();
 alert.setCanceledOnTouchOutside(false);
 alert.show();

}
Sahil Gaikwad
fuente
Si bien este código puede responder la pregunta, proporcionar un contexto adicional con respecto a cómo y / o por qué resuelve el problema mejoraría el valor a largo plazo de la respuesta.
Piotr Labunski