安卓适配器多个getView

8
我已经阅读了有关getView被多次调用的问题以及所有答案。但是,我没有找到解决我的问题的方法。
我有一个列表,其中行有两种状态:已读或未读。我希望第一次看到的项目具有不同的颜色,并且当我滚动列表时,它们会更改为“已读状态”。
为了实现这一点,在我的适配器的getView方法中,当为该项绘制行时,我设置了一个isRead字段。但是问题是:由于getView方法被多次调用,该字段被标记为已读,并且当列表在屏幕上显示时,它看起来好像已经被读过了。
有什么办法解决这个问题吗?
谢谢
4个回答

14

我假设你指的是getView请求多次相同视图的问题。

ListView这样做是因为它需要获取不同原因(滚动条大小、布局等)的视图测量值。

通常可以通过在listview上不使用“wrap_content”属性来避免此问题。

除此之外,使用getView来确定视图是否已显示只是一个糟糕的想法。 ListView有许多优化程序来处理每一行调用getView的顺序,因此无法预知会发生什么,您的应用程序将开始显示奇怪的行为。

尽量避免视图与数据之间的任何关系,除了视图作为该数据的显示概念。

相反,让列表活动中的某个工作线程或事件监听器监视该列表,更新数据,并在您的适配器上调用dataSetChanged来更改已显示给用户的列表项。


更新数据,并在适配器上调用dataSetChanged - 对我有效。 - Andrei Aulaska

1

我曾经遇到过同样的问题,而且在布局属性中根本没有任何关于“wrap_content”的参考。虽然这是一个旧的线程,但我仍然无法解决这个问题。因此,我通过在适配器中添加一个列表来保存已绘制的位置来缓解它,如下面的代码所示。我认为这不是正确的做法,但对我有效。

public class ImageAdapter extends BaseAdapter {
    private Context mContext;
    private List<Integer> usedPositions  = new ArrayList<Integer>();

    public ImageAdapter(Context c, List<String> imageUrls) {
        mContext = c;
        ...
    }

    ...

    // create a new ImageView for each item referenced by the Adapter
    public View getView(int position, View convertView, ViewGroup parent) {
        ImageView imageView;
        if (convertView == null) { 
            imageView = new ImageView(mContext);
            imageView.setLayoutParams(new GridView.LayoutParams(85, 85));
            imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
            imageView.setPadding(8, 8, 8, 8);
        } else {
            imageView = (ImageView) convertView;
        }

        if (!usedPositions.contains(position)) {
            // Your code to fill the imageView object content
            usedPositions.add(position); // holds the used position
        }

        return imageView;
    }
}

0

它不是按照你期望的方式工作。调用getView()多次的原因是为了允许操作系统测量行高,以便知道如何布局。当用户单击或勾选框时,您需要将其标记为已读。


0
这里有一个非常简单的方法,可以避免双重调用,当你知道此代码块以下的任何内容都不会扭曲布局时。
private static List<String> usedPositions  = new ArrayList<String>();

...

@Override
public View getView(int position, View rowView, ViewGroup parent) {
    rowView = inflater.inflate(R.layout.download_listview_item, null);

    Log.d(LOG_TAG, "--> Position: " + position);

    if (!usedPositions.contains(String.valueOf(position))){
        usedPositions.add(String.valueOf(position));
        return rowView;
    }else{
        usedPositions.remove(String.valueOf(position));
    }

...


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接