ListView项着色选择无法在Android API版本8/9中正常工作
我目前使用ListView来显示某种项目。我已经实现了一个动作模式来选择多个项目并大量删除,这在Android 4.x中效果很好。但是,当我尝试使用API版本8或9(android 2.2.x/2.3.x)时,选择内部按预期工作,但行项目随机着色。ListView项着色选择无法在Android API版本8/9中正常工作
如果用户选择第一行,则选择内部第一行,但行号4是彩色的。当我点击另一行时,这一行和第一行是彩色的。这是一种奇怪的行为,我希望在4.x设备上正常工作。
长按覆盖激活动作模式,并检查的ListView长单击项目:
@Override
public boolean onItemLongClick(AdapterView<?> adapterView, View view, int position, long id) {
if (actionMode == null) {
listView.setOnItemClickListener(new CABClickListener());
actionMode = startActionMode(new ListActionMode());
// Check item pressed with long click
listView.setItemChecked(position, true);
view.setBackgroundColor(checkedColor);
logger.debug("Item at pos. " + position + ", checked.");
}
return true;
}
CABClickListener,负责检查的ListView /取消选中的项目,内部标记,并改变其背景色:
private final class CABClickListener implements AdapterView.OnItemClickListener {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
if (listView.isItemChecked(position)) {
view.setBackgroundColor(checkedColor);
logger.debug("Item at pos. " + position + ", checked.");
} else {
view.setBackgroundColor(uncheckedColor);
logger.debug("Item at pos. " + position + ", unchecked.");
}
}
}
这些类/方法在Activity中,listView
在它的顶部声明。
更多的考虑:
- 使用ActionBarSherlock(它显示了CAB,但我认为这不是 这里重要的)和Roboguice,但我没有与任何问题。
-
我一直在用模拟器开发。另外,我无法使用android 3.x来试用我的应用程序(遇到此版本的问题,仿真器无法启动),所以我不知道这些版本中是否存在问题。更新:在Android 3.0 API 11中测试,在4.x上运行良好。 - 我调试的代码和
View
s在这两种方法都可以,但是当我打电话给view.setBackgroundColor(checkedColor);
时,另一个View
是彩色的。
有什么建议吗?希望任何人都能帮忙!
哇,这个问题是在我自己实现的ArrayAdapter
,我试图应用视图模式。我最初放弃了这个,因为我测试了一个简单的ArrayAdapter
,问题仍然存在。
android APIs之间的区别是,当在8-10 API中单击项目时,所有列表都会重新绘制,重用现有视图。因此,当你点击一个项目(视图)时,这是有颜色但立即android重新绘制所有列表,重新使用视图,并使有色的一个在其他位置。当> 11 API中的列表视图项被点击时,任何东西都会被重新绘制(是的,版本之间有很大的性能改进),并且正确的项目视图被成功绘制(正确调用view.setBackgroundColor(checkedColor)
)。
最后,我解决了这个奇怪的行为,将检查状态存储在实体中。因此,当必须回收视图时,可以恢复检查值,并且清单项目可以毫无问题地着色。
我张贴我的GenericListAdapter.getView()方法和相关的任何感兴趣的人。
GenericListAdapter<T>.getView()
:
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ItemViewHolder<T> viewHolder = null;
if (convertView == null || !(convertView.getTag() instanceof ItemViewHolder<?>)) {
logger.debug("New view: " + convertView + " at position: " + position);
LayoutInflater mInflater = LayoutInflater.from(context);
convertView = mInflater.inflate(resource, null);
viewHolder = GenericViewHolderFactory.createInstance(clazz);
viewHolder.setContext(context);
viewHolder.saveViewContents(convertView);
convertView.setTag(viewHolder);
} else {
logger.debug("Reusing view: " + convertView + ", at position: " + position);
viewHolder = (ItemViewHolder<T>) convertView.getTag();
}
T entity = getItem(position);
viewHolder.setViewFields(entity, convertView);
return convertView;
}
而且ViewHolder
执行其刷新回收的观点:
public class EventItemViewHolder implements ItemViewHolder<Event> {
...
@Override
public void setViewFields(Event event, View convertView) {
name.setText(event.getName());
amount.setText(event.getTotalAmount().toString());
if (event.isChecked()) {
convertView.setBackgroundColor(checkedColor);
} else {
convertView.setBackgroundColor(uncheckedColor);
}
}
}
我希望我已经解释自己很好。
而[这里](http://pastebin.com/aTNHqHiR)是我的类,当ActionMode处于活动状态时,它处理listView项目OnClick。 – jelies 2012-07-30 09:31:04
你可以解释完整的代码 – arul 2014-01-21 11:59:10