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); 
     } 
    } 
} 

我希望我已经解释自己很好。

+1

而[这里](http://pastebin.com/aTNHqHiR)是我的类,当ActionMode处于活动状态时,它处理listView项目OnClick。 – jelies 2012-07-30 09:31:04

+0

你可以解释完整的代码 – arul 2014-01-21 11:59:10