arveltのソフトウェア技術メモ

Arvelt's software technology memo

AndroidでDialogのsetMultiChoiceItemsメソッドの使い方

 Androidの連絡帳アプリを作成している。ダイアログで連絡先の一覧をチェックボックス付で表示したいなーと思ったときの処理のやり方について。
setMultiChoiceItemsにはシグネチャが3種類ある。リファレンスより。

1.setMultiChoiceItems(CharSequence[] items, boolean[] checkedItems,DialogInterface.OnMultiChoiceClickListener listener)
2.setMultiChoiceItems(Cursor cursor, String isCheckedColumn, String labelColumn, DialogInterface.OnMultiChoiceClickListener listener)
3.setMultiChoiceItems(int itemsId, boolean[] checkedItems, DialogInterface.OnMultiChoiceClickListener listener)

1と3はわりとわかりやすい。引数の1つ目が表示したい項目、2つ目は項目のチェック状態、3つ目がリスナー。
2の使い方がよくわからない。ADKに含まれるサンプルは項目のチェック状態の処理やボタンが押された後の処理が入っていない。それではメソッドの使い方がわからない。連絡帳のカーソルをセットしたら、確かに一覧表示はできる。だがチェック項目の保持と取り出しができない。なんのためのサンプルなんだ?

ぐぐっても余り情報が出てこない。1と3の使い方はたくさん見つかるが、2の使い方はでてこない。かろうじてこの最後の人が言及しているやり方ではないかと思われる。
チェック状態をカーソルに保持しなければいけない、と言ってるように読める。だがこのカーソルはContactsの検索結果だ。勝手に列を追加することはできないだろう。

試行錯誤の末、以下のようにすれば連絡先の一覧をチェックボックス付でダイアログに表示できた。
Contactsを検索して、配列に入れなおして、1の構文を使って表示している。
アプリのビジネスロジックを省くために一部改変してある。そのまま貼りつけただけでは動かないと思われることを申し添えておく。

//CONTACTSのID、名前、check状態を配列で保持する
Cursor c = getContentResolver().query(Contacts.CONTENT_URI, null , null, null, Contacts.DISPLAY_NAME);
final String[] contactsId = new String[c.getCount()];
final String[] contactsName = new String[c.getCount()];
final boolean[] contactsChecked = new boolean[c.getCount()];;

int i = 0;
while(c.moveToNext()){
  contactsId[i]= c.getString(c.getColumnIndex(Contacts._ID));
  contactsName[i] = c.getString(c.getColumnIndex(Contacts.DISPLAY_NAME)) ;
  contactsChecked[i]=false
  i++;
}

//ダイアログ表示
final AlertDialog.Builder alertDialogBuilde = new AlertDialog.Builder(this);
alertDialogBuilde.setTitle("Select contacts")
.setMultiChoiceItems(contactsName, contactsChecked, new OnMultiChoiceClickListener() {
      
  @Override
  public void onClick(DialogInterface dialog, int which, boolean isChecked) {
    //リストのアイテムが選択されたときの動作
    contactsChecked[which] = isChecked ;
  }
})
.setPositiveButton("OK", new OnClickListener() {
  
  @Override
  public void onClick(DialogInterface dialog, int which) {
    //OKボタンが押されたときの動作
    //contactsCheckedをループしてtrueのときのcontactsIdがチェックされている連絡先となる
  }
})
.setNegativeButton("Cancel", new OnClickListener() {
  
  @Override
  public void onClick(DialogInterface dialog, int which) {
    //Cancelボタンが押されたときの動作
  }
})
.create()
.show();