我想在实际上不允许使用的ActionBarSherlock中使用上下文菜单。ListView.CHOICE_MODE_MULTIPLE_MODAL
我已经为列表中的多选项目创建了自己的实现,但问题是(实际上在其他情况下这是一个很棒的功能)android在ListView
. 我通过着色它们的背景以将它们标记为选中来处理列表上的多选项目,此外我将选择存储在SparseArray
但现在没关系,因为它工作得很好。
您可以猜到,从我选择的项目开始,我的列表中每 10 个项目都会复制背景颜色。
那么我应该怎么做才能为每个列表项提供不同的视图呢?或者也许有另一种解决这个问题的方法?
我用SimpleCursorAdapter
withViewBinder
来填写我的列表项。
/***************************************
******** ACTION MODES HANDLING ********
***************************************/
@Override
public boolean onItemLongClick(AdapterView<?> parent, View v, int position, long id) {
switchActionMode();
if (isInActionMode) {
checkItem(position, v);
startActionMode();
}
else {
uncolorAndClearAllItems();
actionMode.finish();
}
return true;
}
private void switchActionMode() {
isInActionMode ^= true;
}
private void checkItem(int position, View v) {
boolean isChecked = isItemChecked(position);
setItemChecked(position, v, !isChecked);
colorItem(v, !isChecked);
}
private boolean isItemChecked(int position) {
return checkedItems.get(position, false);
}
private void startActionMode() {
actionMode = activity.startActionMode(new ActionModeCallback());
}
private void setItemChecked(int position, View v, boolean isChecked) {
if (isChecked) {
checkedItems.put(position, true);
}
else {
checkedItems.delete(position);
}
}
private void colorItem(View v, boolean isChecked) {
int color;
if (isChecked) {
color = COLOR_BLUE;
}
else {
color = Color.TRANSPARENT;
}
v.setBackgroundColor(color);
}
private void colorItem(int position, boolean isChecked) {
View listItemView = listView.getChildAt(position);
colorItem(listItemView, isChecked);
}
private final class ActionModeCallback implements ActionMode.Callback {
@Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
activity.getSupportMenuInflater().inflate(R.menu.list_action_menu, menu);
return true;
}
@Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
isInActionMode = true;
swipeDismissList.pause();
return true;
}
@Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
int itemsSize = checkedItems.size();
switch (item.getItemId()) {
case R.id.menu_dismiss:
dismissFeeds(itemsSize);
break;
case R.id.menu_mark_as_read:
markFeedsAsRead(itemsSize);
break;
}
restartLoaderIfNecessary(itemsSize);
mode.finish();
return true;
}
private void dismissFeeds(int itemsSize) {
ArrayList<Feed> feeds = new ArrayList<Feed>();
for (int i = itemsSize - 1; i >= 0; i--) {
int position = checkedItems.keyAt(i);
Feed dismissedFeed = dismissFeedAndReturn(position);
feeds.add(dismissedFeed);
}
createUndoAction(feeds, R.string.undobar_message_deleted_selected, Action.DISMISSED);
}
private void markFeedsAsRead(int itemsSize) {
ArrayList<Long> feedsIDs = new ArrayList<Long>();
for (int i = itemsSize - 1; i >= 0; i--) {
int position = checkedItems.keyAt(i);
Feed readFeed = markFeedAsReadAndReturn(position);
feedsIDs.add(readFeed.ID());
}
createUndoAction(feedsIDs, R.string.undobar_message_read_selected, Action.READ);
}
private void createUndoAction(ArrayList<? extends Serializable> feedsIDs, int messageId, Action actionType) {
UndoableCollection undoableAction = new UndoableCollection(feedsIDs, actionType);
undoBarController.showUndoBar(undoableAction, messageId);
}
private void restartLoaderIfNecessary(int itemsSize) {
if (itemsWillChange(itemsSize)) {
restartLoader();
}
}
private boolean itemsWillChange(int itemsSize) {
return itemsSize != 0;
}
@Override
public void onDestroyActionMode(ActionMode mode) {
isInActionMode = false;
swipeDismissList.resume();
uncolorAndClearAllItems();
}
}
private void uncolorAndClearAllItems() {
int size = checkedItems.size();
for (int i = size - 1; i >= 0; i--) {
int position = checkedItems.keyAt(i);
colorItem(position, false);
}
checkedItems.clear();
}
@Override
public void onListItemClick(ListView l, View v, int position, long id) {
super.onListItemClick(l, v, position, id);
if (isInActionMode) {
checkItem(position, v);
clearCheckedItemsIfNoSelection();
}
}
private void clearCheckedItemsIfNoSelection() {
if (noItemSelected()) {
checkedItems.clear();
actionMode.finish();
}
}
private boolean noItemSelected() {
return checkedItems.size() == 0;
}
SimpleCursorAdapter
class FeedCursorAdapter(context: Context, cursor: Cursor)
extends SimpleCursorAdapter(
context,
R.layout.list_item,
cursor,
Array(C_TITLE, C_SITE, C_ADDED_DATE, C_IMAGE),
Array(R.id.textViewFeedTitle, R.id.textViewChannelSite, R.id.textViewFeedDate, R.id.imageViewFeedImage),
0) {
setViewBinder(new FeedCursorViewBinder(context))
}
ViewBinder
class FeedCursorViewBinder(context: Context) extends SimpleCursorAdapter.ViewBinder {
implicit def int2bool(int: Int) = if (int == 1) true else false
implicit def longDate2String(longDate: Long) = new Date(longDate).toLocaleString
private lazy val bitmapUtils = new BitmapUtils(context)
override def setViewValue(view: View, cursor: Cursor, columnIndex: Int) = {
/**
* Get columns indexes from cursor
*/
def getColumnIndex(columnName: String) = cursor.getColumnIndex(columnName)
val indexTitle = getColumnIndex(C_TITLE)
val indexRead = getColumnIndex(C_READ)
val indexDate = getColumnIndex(C_ADDED_DATE)
val indexImage = getColumnIndex(C_IMAGE)
val indexChannel = getColumnIndex(C_CHANNEL)
val indexSite = getColumnIndex(C_SITE)
def setTextAndColor(index: Int) = {
val text = cursor.getString(index)
val textView = view.asInstanceOf[TextView]
textView.setTextColor(getTextColor)
textView.setText(text)
true
}
def getTextColor = {
val isRead: Boolean = cursor.getInt(indexRead)
if (isRead) Color.GRAY
else Color.BLACK
}
columnIndex match {
case `indexTitle` | `indexSite` => setTextAndColor(columnIndex)
case `indexImage` => {
val imageId: Int = cursor.getInt(indexImage)
val imageFromFile = bitmapUtils.readBitmapForFeed(imageId)
val feedImage =
if (imageFromFile != null) imageFromFile
else BitmapFactory.decodeResource(context.getResources, imageId)
val imageViewFeedImage = view.asInstanceOf[ImageView]
imageViewFeedImage.setImageBitmap(feedImage)
true
}
case `indexDate` => {
val dateLong = cursor.getLong(indexDate)
val textViewFeedDate = view.asInstanceOf[TextView]
textViewFeedDate.setText(dateLong)
true
}
case _ => false
}
}
}
也许我会明确我的问题: