MultiChoiceModeListenerが提供されていないため、ActionBarSherlockを使用してAdapterViewに複数選択を実装するにはどうすればよいですか?
こんな感じです
どうすればできますか?
だからここに私がやったことがある。
編集:以前の回答に無用のコード(woops)がたくさんあり、CABのことははるかに少ない労力とよりクリーンなコードで達成できることを知ってから1年以上経過したため、少し時間をかけて更新しました
LibraryFragment ListViewは選択モード「なし」で定義する必要があります
<ListView
Android:id="@Android:id/list"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:choiceMode="none"/>
強調表示された半透明のオーバーレイをlist.setItemChecked(pos、true)に自動的に描画するには、リストアイテムに?attr/activatedBackgroundIndicatorフォアグラウンドが必要です。
list_item_library.xml
<FrameLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:foreground="?attr/activatedBackgroundIndicator"
Android:paddingBottom="5dp"
Android:paddingTop="5dp" >
....
The ListFragment
import Android.support.v4.app.DialogFragment;
import com.actionbarsherlock.app.SherlockListFragment;
import com.actionbarsherlock.view.ActionMode;
import com.actionbarsherlock.view.Menu;
public final class LibraryFragment
extends SherlockListFragment
{
private MyListAdapter adapter;
private ListView list;
// if ActoinMode is null - assume we are in normal mode
private ActionMode actionMode;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
{
View v = inflater.inflate(R.layout.fragment_library, null);
this.list = (ListView) v.findViewById(Android.R.id.list);
this.initListView();
return v;
}
@Override
public void onPause()
{
super.onPause();
if (this.actionMode != null) {
this.actionMode.finish();
}
}
@Override
public void onResume() {
super.onResume();
updateData();
}
// update ListView
protected void updateData()
{
if (adapter == null) {
return;
}
adapter.clear();
// my kinda stuff :)
File[] items = scan();
if (items != null) {
adapter.updateData(items);
if (actionMode != null) {
actionMode.invalidate();
}
}
// if empty - finish action mode.
if (actionMode != null && (files == null || files.length == 0)) {
actionMode.finish();
}
}
private void initListView()
{
this.adapter = new MyAdapter(getActivity());
this.list.setAdapter(adapter);
this.list.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener()
{
@Override
public boolean onItemLongClick(AdapterView<?> arg0,
View arg1, int arg2, long arg3)
{
if (actionMode != null) {
// if already in action mode - do nothing
return false;
}
// set checked selected item and enter multi selection mode
list.setChoiceMode(AbsListView.CHOICE_MODE_MULTIPLE);
list.setItemChecked(arg2, true);
getSherlockActivity().startActionMode(
new ActionModeCallback());
return true;
}
});
this.list.setOnItemClickListener(new AdapterView.OnItemClickListener()
{
@Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3)
{
if (actionMode != null) {
// the items are auomatically "checked" becaise we've set AbsListView.CHOICE_MODE_MULTIPLE before
// starting action mode, so the only thing we have to care about is invalidating the actionmode
actionMode.invalidate(); //invalidate title and menus.
} else {
// do whatever you should on item click
}
}
});
}
// all our ActionMode stuff here :)
private final class ActionModeCallback
implements ActionMode.Callback
{
// " selected" string resource to update ActionBar text
private String selected = getActivity().getString(
R.string.library_selected);
@Override
public boolean onCreateActionMode(ActionMode mode, Menu menu)
{
actionMode = mode;
return true;
}
@Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu)
{
// remove previous items
menu.clear();
final int checked = list.getCheckedItemCount();
// update title with number of checked items
mode.setTitle(checked + this.selected);
switch (checked) {
case 0:
// if nothing checked - exit action mode
mode.finish();
return true;
case 1:
// all items - rename + delete
getSherlockActivity().getSupportMenuInflater().inflate(
R.menu.library_context, menu);
return true;
default:
getSherlockActivity().getSupportMenuInflater().inflate(
R.menu.library_context, menu);
// remove rename option - because we have more than one selected
menu.removeItem(R.id.library_context_rename);
return true;
}
}
@Override
public boolean onActionItemClicked(ActionMode mode,
com.actionbarsherlock.view.MenuItem item)
{
SparseBooleanArray checked;
switch (item.getItemId()) {
case R.id.library_context_rename:
// the rename action is present only when only one item is selected.
// so when the first checked item found, show the dialog and break
checked = list.getCheckedItemPositions();
for (int i = 0; i < checked.size(); i++) {
final int index = checked.keyAt(i);
if (checked.get(index)) {
final DialogFragment d = RenameDialog.instantiate(adapter.getItem(index).getFile(), LibraryFragment.this);
d.show(getActivity().getSupportFragmentManager(), "dialog");
break;
}
}
return true;
case R.id.library_context_delete:
// delete every checked item
checked = list.getCheckedItemPositions();
for (int i = 0; i < checked.size(); i++) {
final int index = checked.keyAt(i);
if (checked.get(index)) {
adapter.getItem(index).getFile().delete();
}
}
updateData();
return true;
default:
return false;
}
}
@Override
public void onDestroyActionMode(ActionMode mode)
{
list.clearChoices();
//workaround for some items not being unchecked.
//see http://stackoverflow.com/a/10542628/1366471
for (int i = 0; i < list.getChildCount(); i++) {
(list.getChildAt(i).getBackground()).setState(new int[] { 0 });
}
list.setChoiceMode(AbsListView.CHOICE_MODE_NONE);
actionMode = null;
}
}
あなたのソリューションは、このスレッドに最適で最も簡単なソリューションです。しかし、getView()には小さな問題があります-上記の私のコメントを参照してください。
int version = Android.os.Build.VERSION.SDK_INT;
if(version < 11){
if (checkedItems.contains(Integer.valueOf(position))) {
convertView.getBackground().setState(
new int[] { Android.R.attr.state_checked });
} else {
convertView.getBackground().setState(
new int[] { -Android.R.attr.state_checked });
}
}else{
if (checkedItems.contains(Integer.valueOf(position))) {
convertView.setActivated(true);
} else {
convertView.setActivated(false);
}
}
これにより、API8からAPI18までの完全なサポートが提供されます