我已经阅读了多次调用getView的问题和所有答案。但是,我找不到解决问题的方法。
我有一个列表,其中行有两种状态:读取或不读取。好吧,我想第一次看到的项目有不同的颜色,当我滚动列表时,他们将颜色改为“读状态”。
为了做到这一点,在我的适配器的getView方法中,当绘制该项的行时,我设置了一个字段isRead。但问题如下:由于方法getView被多次调用,字段被标记为已读,当列表显示在屏幕上时,它看起来好像已经被读取了。
有什么想法解决这个问题吗?
由于
答案 0 :(得分:14)
我认为你的意思是getView多次请求相同的视图。
ListView这样做是因为它需要根据不同的原因(滚动条大小,布局等)获取视图的测量值
通常可以通过不使用listview上的“wrap_content”属性来避免此问题。
除此之外,使用getView确定是否已显示视图只是一个坏主意。 ListView有许多优化,每行调用getView命令,所以没有办法知道会发生什么,你的应用程序将开始显示奇怪的行为。
尽量避免视图和视图概念之外的任何关系作为该数据的显示。
相反,在listactivity中有一些工作线程或事件监听器,查看列表中的项目已显示给用户的列表,更新数据,并在适配器上调用dataSetChanged。
答案 1 :(得分:1)
我遇到了同样的问题,我在布局attirbute中根本没有引用“wrap_content”。虽然这是一个老线程,但我无法弄清楚如何解决这个问题。因此,我通过在适配器中添加一个List来缓解它,该List保存已经绘制的位置,如下面的代码所示。我认为不是那样做的,但它对我有用。
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;
}
}
答案 2 :(得分:0)
不是你希望它的工作方式。多次调用getView()
的原因是允许操作系统测量行,以便知道如何布局它们。您需要在点击它或选中一个框或其他内容时将其标记为已读。
答案 3 :(得分: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));
}
...