2011-05-12 13 views
14

Tengo un cuadro de diálogo con casillas de verificación y estaba tratando de hacer cosas diferentes cuando se seleccionan las opciones y cuando se presiona la tecla ok. Pensé que sabía lo que estaba haciendo después de leer algunos tutoriales, pero cuando presiono "Aceptar" simplemente brinda por "Todo", incluso si no está marcado. Parece que mis declaraciones if no funcionan correctamente, pero no sé por qué.Diálogo de casilla de verificación de Android (fácil)

Me agradecerán cualquier sugerencia sobre lo que estoy haciendo mal y cómo solucionarlo.

final CharSequence[] items = {"Item 1", "Item 2", "Item 3"}; 
    final boolean[] states = {false, false, false}; 
    AlertDialog.Builder builder = new AlertDialog.Builder(this); 
    builder.setTitle("What would you like to do?"); 
    builder.setMultiChoiceItems(items, states, new DialogInterface.OnMultiChoiceClickListener(){ 
     public void onClick(DialogInterface dialogInterface, int item, boolean state) { 
     } 
    }); 
    builder.setPositiveButton("Okay", new DialogInterface.OnClickListener() { 
     public void onClick(DialogInterface dialog, int id) { 
      SparseBooleanArray CheCked = ((AlertDialog)dialog).getListView().getCheckedItemPositions(); 
      if(CheCked.get(CheCked.keyAt(0)) == true){ 
       Toast.makeText(Backup.this, "Item 1", Toast.LENGTH_SHORT).show(); 
      } 
      if(CheCked.get(CheCked.keyAt(1)) == true){ 
       Toast.makeText(Backup.this, "Item 2", Toast.LENGTH_SHORT).show(); 
      } 
      if(CheCked.get(CheCked.keyAt(2)) == true){ 
       Toast.makeText(Backup.this, "Item 3", Toast.LENGTH_SHORT).show(); 
      } 
     } 
    }); 
    builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() { 
     public void onClick(DialogInterface dialog, int id) { 
      dialog.cancel(); 
     } 
    }); 
    builder.create().show(); 
} 

Respuesta

7

El problema es que utilice keyAt, que, de acuerdo con API Docs

devuelve la llave del indexth asignación de clave-valor que almacena SparseBooleanArray.

y esto SparseBooleanArray contiene sólo los elementos seleccionados de la lista (getCheckedItemPositions)!

Así que si marca dos elementos de tres, entonces el miembro CheCked contendrá artículos 2, y cuando se llama keyAt(2) se devolverá 0 (no IndexOutOfBoundsException, aunque en esa posición el mapa no se sostiene valor).

Lo que debe utilizar es simplemente el método get de esta SparseBooleanArray, con las posiciones de los elementos de su ListView como argumentos:

builder.setPositiveButton("Okay", new DialogInterface.OnClickListener() 
{ 
    public void onClick(DialogInterface dialog, int id) 
    { 
     SparseBooleanArray CheCked = ((AlertDialog) dialog).getListView().getCheckedItemPositions(); 
     if (CheCked.get(0)) 
     { 
      Toast.makeText(TmpActivity2.this, "Item 1", Toast.LENGTH_SHORT).show(); 
     } 
     if (CheCked.get(1)) 
     { 
      Toast.makeText(TmpActivity2.this, "Item 2", Toast.LENGTH_SHORT).show(); 
     } 
     if (CheCked.get(2)) 
     { 
      Toast.makeText(TmpActivity2.this, "Item 3", Toast.LENGTH_SHORT).show(); 
     } 
    } 
}); 

También puede perder la parte == true de la cláusula if, pero eso es sólo semántica .

Si se echa un vistazo a los API Docs del método getCheckedItemPositions, a encontrar esta solución:

devoluciones:
Un SparseBooleanArray que devolverá cierto para cada llamada a get(int position) donde position es una posición en la lista, o null si el modo de elección se establece en CHOICE_MODE_NONE.

+0

Perfecto gracias de los dos métodos funcionan bien – GFlam

+0

@rekaszenu Creo que esta solución también es mejor. Especialmente para listas grandes Loop necesita más recursos. – evilone

+0

Es (casi) siempre mejor usar la API que las soluciones, pero en la mayoría de los casos es aburrido leer los documentos; :) esto resulta en el manejo del miembro 'CheCked' como un' Mapa' completo de los elementos 'ListView' y su estado verificado. – rekaszeru

10

lo haría así por ejemplo:

public class Main extends Activity { 

    CharSequence[] items = {"Google", "Apple", "Microsoft"}; 
    boolean[] itemsChecked = new boolean[items.length]; 

    /** Called when the activity is first created. */ 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 

     Button btn = (Button) findViewById(R.id.btnDialog); 
     btn.setOnClickListener(new OnClickListener() { 

      @Override 
      public void onClick(View v) { 
       showDialog(0); 
      } 
     }); 
    } 

    @Override 
    protected Dialog onCreateDialog(int id) { 
     switch (id) { 
     case 0: 
      return new AlertDialog.Builder(this) 
      .setIcon(R.drawable.icon) 
      .setTitle("Dialog with simple text") 
      .setPositiveButton("OK", new DialogInterface.OnClickListener() { 

       @Override 
       public void onClick(DialogInterface dialog, int which) { 
        for (int i = 0; i < items.length; i++) { 
        if (itemsChecked[i]) { 
         Toast.makeText(getBaseContext(), items[i] + " checked!", Toast.LENGTH_LONG).show(); 
        } 
       } 
       } 
      }) 
      .setNegativeButton("Cancel", new DialogInterface.OnClickListener() { 

       @Override 
       public void onClick(DialogInterface dialog, int which) { 
        Toast.makeText(getBaseContext(), "Cancel clicked!", Toast.LENGTH_LONG).show(); 
       } 
      }) 
      .setMultiChoiceItems(items, itemsChecked, new DialogInterface.OnMultiChoiceClickListener() { 

       @Override 
       public void onClick(DialogInterface dialog, int which, boolean isChecked) { 
        Toast.makeText(getBaseContext(), items[which] + (isChecked ? "checked!" : "unchecked!"), Toast.LENGTH_SHORT).show(); 
       } 
      }) 
      .create(); 
     } 

     return null; 
    } 


} 
+0

No quiero que las cosas funcionen onClick aunque yo quiero lo que está comprobado que se ejecute cuando se presiona bien y sólo cuando se presiona bien no puedo tener los elementos corren onClick – GFlam

+1

editado mi código, pero te quiero piensa un poco mas duroNo es tan difícil agregar un método de bucle a onClick y comprobar qué elemento de la matriz tiene un valor de verdadero :) – evilone

+0

Lo siento, soy nuevo en esto, he estado aprendiendo java en mi tiempo libre durante el último mes, pero de todos modos he estado cansado como el infierno. también he estado yendo a esta aplicación durante las últimas horas de descanso :) pero tu método funcionó muy bien, al igual que el otro solo les di el cheque porque era más simple porque ya tenía ese como mi código y explicaba lo que había hecho mal deseo podría darles a ustedes los dos cheques pero también les di un voto positivo – GFlam

2

esto debería ayudar

.setMultiChoiceItems(items, itemsChecked, 
         new DialogInterface.OnMultiChoiceClickListener() { 
          @Override 
          public void onClick(DialogInterface dialog, 
            int which, boolean isChecked) { 




           Toast.makeText(
             getBaseContext(), 
             items[which] 
               + (isChecked ? " checked!" 
                 : " unchecked!"), 
             Toast.LENGTH_SHORT).show(); 
          } 
         }) 

Pero entonces, ¿cómo utilizar los elementos marcados en otra clase?

Cuestiones relacionadas