J'utilise le code suivant quand je veux obtenir exactement la même chose que vous avez décrit:
/*
* Copyright 2012 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.maddogs.mymoney.utils;
import java.util.HashSet;
import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.support.v7.app.ActionBarActivity;
import android.support.v7.view.ActionMode;
import android.util.Pair;
import android.util.SparseBooleanArray;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AbsListView;
import android.widget.Adapter;
import android.widget.AdapterView;
import android.widget.ListView;
/**
* Utilities for handling multiple selection in list views. Contains
* functionality similar to {@link AbsListView#CHOICE_MODE_MULTIPLE_MODAL} but
* that works with {@link ActionBarActivity} and backward-compatible action
* bars.
*/
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
public class MultiSelectionUtil {
public static Controller attachMultiSelectionController(
final ListView listView, final ActionBarActivity activity,
final MultiChoiceModeListener listener) {
return Controller.attach(listView, activity, listener);
}
@SuppressLint("NewApi")
public static class Controller implements ActionMode.Callback,
AdapterView.OnItemClickListener,
AdapterView.OnItemLongClickListener {
private Handler mHandler = new Handler();
private ActionMode mActionMode;
private ListView mListView = null;
private ActionBarActivity mActivity = null;
private MultiChoiceModeListener mListener = null;
private HashSet<Long> mTempIdsToCheckOnRestore;
private HashSet<Pair<Integer, Long>> mItemsToCheck;
private AdapterView.OnItemClickListener mOldItemClickListener;
private Controller() {
}
public static Controller attach(ListView listView,
ActionBarActivity activity, MultiChoiceModeListener listener) {
Controller controller = new Controller();
controller.mListView = listView;
controller.mActivity = activity;
controller.mListener = listener;
listView.setOnItemLongClickListener(controller);
return controller;
}
private void readInstanceState(Bundle savedInstanceState) {
mTempIdsToCheckOnRestore = null;
if (savedInstanceState != null) {
long[] checkedIds = savedInstanceState
.getLongArray(getStateKey());
if (checkedIds != null && checkedIds.length > 0) {
mTempIdsToCheckOnRestore = new HashSet<Long>();
for (long id : checkedIds) {
mTempIdsToCheckOnRestore.add(id);
}
}
}
}
public void tryRestoreInstanceState(Bundle savedInstanceState) {
readInstanceState(savedInstanceState);
tryRestoreInstanceState();
}
public void finish() {
if (mActionMode != null) {
mActionMode.finish();
}
}
public void tryRestoreInstanceState() {
if (mTempIdsToCheckOnRestore == null
|| mListView.getAdapter() == null) {
return;
}
boolean idsFound = false;
Adapter adapter = mListView.getAdapter();
for (int pos = adapter.getCount() - 1; pos >= 0; pos--) {
if (mTempIdsToCheckOnRestore.contains(adapter.getItemId(pos))) {
idsFound = true;
if (mItemsToCheck == null) {
mItemsToCheck = new HashSet<Pair<Integer, Long>>();
}
mItemsToCheck.add(new Pair<Integer, Long>(pos, adapter
.getItemId(pos)));
}
}
if (idsFound) {
// We found some IDs that were checked. Let's now restore the
// multi-selection
// state.
mTempIdsToCheckOnRestore = null; // clear out this temp field
mActionMode = mActivity.startSupportActionMode(Controller.this);
}
}
public boolean saveInstanceState(Bundle outBundle) {
// TODO: support non-stable IDs by persisting positions instead of
// IDs
if (mActionMode != null && mListView.getAdapter().hasStableIds()) {
long[] checkedIds = mListView.getCheckedItemIds();
outBundle.putLongArray(getStateKey(), checkedIds);
return true;
}
return false;
}
private String getStateKey() {
return MultiSelectionUtil.class.getSimpleName() + "_"
+ mListView.getId();
}
@Override
public boolean onCreateActionMode(ActionMode actionMode, Menu menu) {
if (mListener.onCreateActionMode(actionMode, menu)) {
mActionMode = actionMode;
mOldItemClickListener = mListView.getOnItemClickListener();
mListView.setOnItemClickListener(Controller.this);
mListView.setChoiceMode(AbsListView.CHOICE_MODE_MULTIPLE);
mHandler.removeCallbacks(mSetChoiceModeNoneRunnable);
if (mItemsToCheck != null) {
for (Pair<Integer, Long> posAndId : mItemsToCheck) {
mListView.setItemChecked(posAndId.first, true);
mListener.onItemCheckedStateChanged(mActionMode,
posAndId.first, posAndId.second, true);
}
}
return true;
}
return false;
}
@Override
public boolean onPrepareActionMode(ActionMode actionMode, Menu menu) {
if (mListener.onPrepareActionMode(actionMode, menu)) {
mActionMode = actionMode;
return true;
}
return false;
}
@Override
public boolean onActionItemClicked(ActionMode actionMode,
MenuItem menuItem) {
return mListener.onActionItemClicked(actionMode, menuItem);
}
@Override
public void onDestroyActionMode(ActionMode actionMode) {
mListener.onDestroyActionMode(actionMode);
SparseBooleanArray checkedPositions = mListView
.getCheckedItemPositions();
if (checkedPositions != null) {
for (int i = 0; i < checkedPositions.size(); i++) {
mListView.setItemChecked(checkedPositions.keyAt(i), false);
}
}
mListView.setOnItemClickListener(mOldItemClickListener);
mActionMode = null;
mHandler.post(mSetChoiceModeNoneRunnable);
}
private Runnable mSetChoiceModeNoneRunnable = new Runnable() {
@Override
public void run() {
mListView.setChoiceMode(AbsListView.CHOICE_MODE_NONE);
}
};
@Override
public void onItemClick(AdapterView<?> adapterView, View view,
int position, long id) {
boolean checked = mListView.isItemChecked(position);
mListener.onItemCheckedStateChanged(mActionMode, position, id,
checked);
int numChecked = 0;
SparseBooleanArray checkedItemPositions = mListView
.getCheckedItemPositions();
if (checkedItemPositions != null) {
for (int i = 0; i < checkedItemPositions.size(); i++) {
numChecked += checkedItemPositions.valueAt(i) ? 1 : 0;
}
}
if (numChecked <= 0) {
mActionMode.finish();
}
}
@Override
public boolean onItemLongClick(AdapterView<?> adapterView, View view,
int position, long id) {
if (mActionMode != null) {
return false;
}
mItemsToCheck = new HashSet<Pair<Integer, Long>>();
mItemsToCheck.add(new Pair<Integer, Long>(position, id));
mActionMode = mActivity.startSupportActionMode(Controller.this);
return true;
}
}
/**
* @see android.widget.AbsListView.MultiChoiceModeListener
*/
public static interface MultiChoiceModeListener extends ActionMode.Callback {
/**
* @see android.widget.AbsListView.MultiChoiceModeListener#onItemCheckedStateChanged(android.view.ActionMode,
* int, long, boolean)
*/
public void onItemCheckedStateChanged(ActionMode mode, int position,
long id, boolean checked);
}
}
Vous attachez simplement ceci à une activité et listview, mettre en œuvre l'interface et vous avez un multiselection avec le travail actionbar!
Une fois que vous avez défini les écouteurs de clic dans le code, vous n'avez pas besoin de toucher le fichier XML. J'ai implémenté avec succès le comportement que vous visez sans aucune mention de 'cliquer' dans le fichier XML. – ygesher