我已经阅读了多次调用 getView 的问题以及所有答案。但是,我没有找到解决我的问题的方法。
我有一个列表,其中行有两种状态:已读或未读。好吧,我希望第一次看到的项目有不同的颜色,当我滚动列表时,它们会将颜色更改为“读取状态”。
为了做到这一点,在我的适配器的 getView 方法中,当该项目的行被绘制时,我设置了一个字段 isRead。但是问题如下:由于方法 getView 被多次调用,该字段被标记为已读,当列表显示在屏幕上时,它看起来好像已经被读取了。
任何想法来解决这个问题?
谢谢
我假设您的意思是 getView 多次请求相同视图的问题。
ListView 这样做是因为它需要出于不同的原因(滚动条大小、布局等)获取视图的测量值
这个问题通常可以通过不在列表视图上使用“wrap_content”属性来避免。
除此之外,使用 getView 来确定是否已显示视图是一个坏主意。ListView 有许多优化与每行调用 getView 的顺序相混淆,因此无法知道会发生什么,并且您的应用程序将开始显示奇怪的行为。
尽量避免视图和数据之间的任何关系,除了视图作为数据显示的概念。
相反,在您的 listactivity 中使用一些工作线程或事件侦听器来观察列表中的哪些项目已显示给用户,更新数据,并在适配器上调用 dataSetChanged。
我有同样的问题,我在布局属性中根本没有提到“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;
}
}
不是你希望它工作的方式。getView()多次调用的原因是允许操作系统测量行,以便知道如何布置它们。当他们单击它或选中一个框或其他内容时,您需要将其标记为已读。
这是一种非常简单的避免双重调用的方法,当您不知道这段代码下方的任何内容会扭曲布局时。
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));
}
...