最近、ListView で問題が発生しました。その中にチェックボックスのリストがあります。チェックされたアイテムは、startActivityForResult で ListActivity を開始する呼び出しアクティビティに供給されます。ListActivity を呼び出す前にチェックされたアイテムがあった場合、それらのアイテムはそれに渡されるため、ユーザーは最初からやり直すのではなく、以前の選択を編集できます。初めてでも大丈夫です。しかし、ListActivity を再度呼び出して選択を変更したい場合、リストの最初のチェックボックスは次のようになります。リスト内の項目のいずれかがチェックされているかどうかがチェックされているように。実際には、チェック済みとして認識されません。つまり、既に選択されているアイテムをチェックするコードは、最初のアイテムを処理するときに起動せず、選択を再度保存した後、最初のアイテムは親に返されるリストの一部ではありません。明示的にチェックされていません (チェックを外してから再度チェックすることにより)。
この問題を検索したところ、ListView の最初の項目がフォーカスされることがわかったので、試してみました。
listView.setItemsCanFocus(false);
効果なし。空でない選択がある場合にのみアイテムがチェックされるため、実際に機能した場合は驚いたでしょう。私の問題に対処する質問が見つからなかったので、説明した効果をまだ生み出す例に煮詰めました。すべてのコードで申し訳ありませんが、何を探すべきか完全に途方に暮れているため、投稿を減らして問題を説明する方法がわかりません。
呼び出しアクティビティの onCreate および onActivityResult:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
listItems = new ArrayList<String>();
list = (TextView) findViewById(R.id.list);
list.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Bundle extras = new Bundle();
extras.putStringArrayList("item_list", listItems);
Intent i = new Intent(Main.this, CheckBoxListActivity.class);
i.putExtras(extras);
startActivityForResult(i,1);
}
});
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent intent) {
super.onActivityResult(requestCode, resultCode, intent);
Bundle extras = new Bundle();
extras = intent.getExtras();
String[] strings = extras.getStringArray("item_list");
String text = "";
listItems.clear();
for ( String item : strings ) {
text = text + item + ", ";
listItems.add(item);
}
if ( text.length() != 0 ) {
text = text.substring(0, text.length() - 2);
} else {
text = "(nothing here)";
}
list.setText(text);
}
ListActivity の onCreate() と finish():
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.checkbox_list);
listView = getListView();
save = (Button) findViewById(R.id.save_button);
save.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.i(LOG_TAG, "save button clicked");
finish();
}
});
ArrayList<String> itemList = new ArrayList<String>();
itemList.add( "foo" );
itemList.add( "bar" );
itemList.add( "baz" );
itemList.add( "qux" );
itemList.add( "quux" );
checkedItems = getIntent().getExtras().getStringArrayList("item_list");
ArrayAdapter<String> arrayAdapter = new ItemsAdapter(this, R.layout.checkbox_list, itemList);
listView.setAdapter(arrayAdapter);
}
@Override
public void finish() {
Bundle extras = new Bundle();
String[] stringArray = new String[checkedItems.size()];
for ( int i = 0; i < checkedItems.size(); i++) {
stringArray[i] = checkedItems.get(i);
}
extras.putStringArray("item_list", stringArray);
Intent mIntent = new Intent();
mIntent.putExtras(extras);
setResult(RESULT_OK, mIntent);
super.finish();
}
そしてArrayAdapter:
private class ItemsAdapter extends ArrayAdapter<String> {
public ItemsAdapter(Context context, int textViewResourceId, List<String> items) {
super(context, textViewResourceId, items);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
if (v == null) {
LayoutInflater vi = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = vi.inflate(R.layout.checkbox_list_row, null);
}
String entry = getItem(position);
v.setTag(entry);
fillText(v, R.id.checkbox, entry);
return v;
}
private void fillText(View v, int id, String text) {
Log.i(LOG_TAG, "this is fillText, our text is: " + text);
CheckBox checkBox = (CheckBox) v.findViewById(id);
if ( checkedItems.contains(text)) {
Log.i(LOG_TAG, "item has to be checked");
checkBox.setChecked(true);
}
checkBox.setText(text == null ? "" : text);
checkBox.setOnCheckedChangeListener(new OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton cb, boolean isChecked) {
String tag = (String) cb.getTag();
if (cb.isChecked()) {
// add item to set of checkedItems
if ( !checkedItems.contains(tag)) {
checkedItems.add(tag);
Log.i(LOG_TAG, "checkedItems: " + checkedItems.toString());
}
} else {
// remove item from set of checkedItems
if ( checkedItems.contains(tag)) {
checkedItems.remove((String) cb.getTag());
Log.i(LOG_TAG, "checkedItems: " + checkedItems.toString());
}
}
}
});
}
}