ListView项上选择着色无法正常运行的Andr​​oid API版本8/9正常运行、版本、ListView、Andr

2023-09-05 08:57:02 作者:期待你到來

我目前使用一个ListView显示排序项。我实现了一个操作模式,可以选择多个项目,并删除大量在安卓4.x的效果很好但是,当我试着用API版本8或9(机器人的2.2.x / 2.3.x),选择内部工作原理预期,但行项目是随机的颜色。

I'm currently using a ListView to display a sort of items. I've implemented an action mode to select multiple items and to delete massively that works well in android 4.x. But when I tried with API version 8 or 9 (android 2.2.x/2.3.x), selection works internally as expected but row items are colored randomly.

如果用户选择第一行,在内部被选择第一行,但是行数4被着色。当我点击另一行,该行并第一个是彩色的。这是一个奇怪的现象,我希望常作为4.x的设备一起使用。

If user selects first row, internally first row is selected, but row number 4 is colored. When I click another row, this row and first one is colored. It's a strange behaviour which I expect to work normally as on 4.x devices.

长按覆盖激活行动模式,并检查的ListView长单击项目:

Long-click overriding to activate action mode and check long-clicked item of 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的项目,内部标识,并改变其背景色:

CABClickListener, responsible to check/uncheck items of ListView, marking them internally and changing its background color:

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

这些类/方法的活动里面,的ListView 在它上面的声明。

更多的考虑:

使用ActionBarSherlock(它显示了CAB但我认为这是不 这里重要的)和Roboguice,但我对此没有任何问题。 我总是在发展与模拟器。此外,我不能尽我与Android 3.x的(有问题,这个版本中,仿真器不启动)的应用程序,所以我不知道在这些版本中的问题依然存在更新:测试在安卓3.0 API 11,工作以及对4.x版。 我调试的code和查看 S在这两种方法都行,但是当我打电话 view.setBackgroundColor(checkedColor); ,另一个查看是有色 Using ActionBarSherlock (it shows the CAB but I think this is not important here) and Roboguice, but I haven't any problem with that. I was always developing with the emulator. In addition, I couldn't try my app with android 3.x (got problems with this version, emulator doesn't launch), so I don't know if the problem persists in these versions. UPDATE: Tested in android 3.0 API 11, works well as on 4.x. I debugged the code and Views in both methods are ok, but when I call view.setBackgroundColor(checkedColor);, another View is colored.

任何建议?希望有人可以帮助!

Any suggestion? Hope anyone can help!

推荐答案

哇,这个问题是在我自己的实施 ArrayAdapter ,这里我想申请观点持有者模式。我放弃了这个最初是因为我测试了同一个简单的 ArrayAdapter 和问题仍然存在。

Wow, the problem was in my own implementation of ArrayAdapter, where I tried to apply view holder pattern. I discarded this initially because I tested the same with a simple ArrayAdapter and problem was still there.

Android的API之间的区别是,当项被点击在8-10 API,所有列表粉刷,重复使用现有的观点。因此,当你在一个项目(查看)点击,这是有颜色的,但立刻安卓重绘所有的列表,重复使用的意见,并使得彩色的,可以在其他位置。当列表视图项被点击在> 11 API,任何被重新粉刷(是的,版本之间有很大的性能提升)和正确的项目视图中被画成功地(适当地调用 view.setBackgroundColor(checkedColor))。

The difference between android APIs is that when item is clicked in the 8-10 API, all list is repainted, reusing existing views. Therefore, when you click in a item (View), this is colored but immediatly android repaints all list, reusing the views, and making the colored one to be in other position. When a list view item gets clicked in >11 API, anything gets repainted (yes, great performance improvement between versions) and the correct item view was painted succesfully (calling properly view.setBackgroundColor(checkedColor)).

最后,我解决了这个奇怪的行为,检查存储状态的实体。与此,当视图已经被回收,检查值可以被回收和列表项可以毫无问题地着色。

Finally, I solved this strange behaviour, storing checked state in the entities. With this, when the view has to be recycled, checked value can be recovered and list item can be colored without problems.

我后我的GenericListAdapter.getView()方法和兴趣的人相关。

I post my GenericListAdapter.getView() method and related for anyone interested.

GenericListAdapter&LT; T&GT; .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 的实现,它刷新回收的观点:

And the ViewHolder implementation which refreshes the recycled view:

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

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

I hope I've explained myself well.