2011-05-12 77 views
14

我有一个对话框与复选框,我试图做不同的事情时,选择选项和按下好的时候。我认为在阅读完一些教程后我知道自己在做什么,但是当我按下OK时,即使没有选中它,它也会提醒“一切”。所以看来我的if语句不能正常工作,但我不知道为什么。Android复选框对话框(简单)

任何建议我做错了什么,以及如何解决它将不胜感激!

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

回答

7

的问题是,你使用keyAt,其中,根据API文档

返回从index个 关键这个 SparseBooleanArray存储的键值映射。

和这个SparseBooleanArray只包含您的清单中检查的项目(getCheckedItemPositions)!

因此,如果您选中三项中的两项,那么CheCked成员将包含2个项目,当您拨打keyAt(2)时,它将返回0(不是IndexOutOfBoundsException,尽管该位置地图不具有值)。

你应该使用简单说就是SparseBooleanArrayget方法,从您ListView项目位置作为参数:

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

您也可以松动,如果从句的== true一部分,但是这只是语义。

如果你看一看的getCheckedItemPositions方法的API文档,你会发现这个解决方案:

返回
一个SparseBooleanArray将在每次调用返回true以get(int position)其中position是列表中的一个位置,或者如果选择模式设置为CHOICE_MODE_NONE,则为null

+0

完美的谢谢你们两个都很好的工作 – GFlam 2011-05-12 20:40:14

+0

@rekaszenu我认为这个解决方案也更好。特别是对于大型列表。循环需要更多的资源。 – evilone 2011-05-13 10:39:55

+0

使用api的方式(几乎)总是比使用方法的更好,但在大多数情况下,阅读文档只是无聊; :)这导致将'CheCked'成员作为ListView'项目的完整'Map'和它们的检查状态来处理。 – rekaszeru 2011-05-13 11:03:28

10

我会做这样的例子:

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

我不希望东西在onClick上运行虽然我希望任何检查运行时好的按下,只有当好的时候按下我不能运行onClick – GFlam 2011-05-12 19:32:29

+1

编辑我的代码,但我希望你觉得有点难。将on循环添加到onClick方法并检查哪个数组项的值为true可不是那么困难:) – evilone 2011-05-12 20:03:38

+0

对不起,我很新,这是在过去一个月的空闲时间学习java,但无论如何已经厌倦了作为地狱以及大声笑一直在这个应用程序的过去几个小时的休息时间:)但你的方法工作得很好,就像另一个我只给他们支票,因为它更简单,因为我已经有了,作为我的代码,并解释我是什么做错了希望我可以给你们两个支票,但我也给你一个投票,以及 – GFlam 2011-05-12 20:39:48

2

这应该有助于

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

但随后你如何在其他类中使用检查的项目?