Android 带有 CursorAdapter bindView 的 ListView 在滚动时工作错误
Android ListView with CursorAdapter bindView works erroneous when scrolling
我已经阅读了几个小时的解决方案,但我仍然没有找到正确的答案。我有一个带有 CursorAdapter 的 ListFragment。行如下:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/circle"
android:src="@drawable/white_circle"
android:layout_alignParentStart="true"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textStyle="italic"
android:textColor="#C0C0C0"
android:textSize="20sp"
android:id="@+id/tvStationName"
android:layout_toRightOf="@+id/circle"
android:layout_alignParentTop="true"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:layout_alignBottom="@+id/way"
android:gravity="top|start"
android:layout_marginLeft="5dp"/>
<ImageView
android:id="@+id/way"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_below="@+id/circle"
android:src="@drawable/white_way"/>
</RelativeLayout>
由于 ListFragment 表示一条路线,其中有车站(圆圈)和车站之间的道路(路),我不希望在最后一站之后出现道路。因此,我更改了最后一个 listview 元素的图像资源。问题如下:
如果我向下滚动列表,似乎一切正常。然后,滚动回顶部,如果它是列表的最后一个元素,则在两个中间站之间至少缺少一种方式。当我滚动更多时,我会得到更多丢失的方式,有时我会找回一些,这似乎是随机的。
适配器class的代码如下:
public class StationAdapter extends CursorAdapter {
private static final String TAG = "StationAdapter";
private Route route;
private Cursor storedCursor;
private LayoutInflater storedInflater;
private final class ViewHolder {
public TextView stationTv;
public ImageView stationIv;
public ImageView wayIv;
}
public StationAdapter(Context context, Cursor cursor, Route route) {
super(context, cursor, false);
this.route = route;
this.storedCursor = cursor;
this.storedInflater = LayoutInflater.from(context);
}
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
final LayoutInflater inflater = LayoutInflater.from(context);
View row = inflater.inflate(R.layout.station_list_row, null);
bindView(row, context, cursor);
return row;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (storedCursor.moveToPosition(position)) {
ViewHolder holder;
if (convertView == null) {
convertView = storedInflater.inflate(R.layout.station_list_row, null);
holder = new ViewHolder();
holder.stationTv = (TextView)convertView.findViewById(R.id.tvStationName);
holder.stationIv = (ImageView)convertView.findViewById(R.id.circle);
holder.wayIv = (ImageView)convertView.findViewById(R.id.way);
convertView.setTag(holder);
}
else {
holder = (ViewHolder)convertView.getTag();
}
Station station = DbLoader.getStationByCursor(storedCursor);
// now we use the references
holder.stationTv.setText(station.getName());
if (station.equals(route.lastStation())) {
holder.wayIv.setImageResource(R.drawable.zero_way);
}
}
return convertView;
}
@Override
public void bindView(View view, Context context, Cursor cursor) {
// UI elements
TextView stationTv = (TextView)view.findViewById(R.id.tvStationName);
ImageView wayIv = (ImageView)view.findViewById(R.id.way);
ImageView stationIv = (ImageView)view.findViewById(R.id.circle);
// station by cursor
Station station = DbLoader.getStationByCursor(cursor);
// set UI label
stationTv.setText(station.getName());
if (station.equals(route.lastStation())) {
wayIv.setImageResource(R.drawable.zero_way);
}
}
@Override
public Station getItem(int position) {
getCursor().moveToPosition(position);
return DbLoader.getStationByCursor(getCursor());
}
}
我不想引用太多细节,希望这些就足够了。
提前致谢。
问题是适配器试图提高效率。重用您滚动离开的视图。
如果您有条件更改视图的默认位置,则需要设置视图的默认位置。
例如,如果您更改背景图片。当该视图被回收时,它将在重复使用时使用相同的图像。
if (station.equals(route.lastStation())) {
holder.wayIv.setImageResource(R.drawable.zero_way);
}
例如,需要重置为默认值。
if (station.equals(route.lastStation())) {
holder.wayIv.setImageResource(R.drawable.zero_way);
} else {
holder.wayIv.setImageResource(R.drawable.white_way);
}
我已经阅读了几个小时的解决方案,但我仍然没有找到正确的答案。我有一个带有 CursorAdapter 的 ListFragment。行如下:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/circle"
android:src="@drawable/white_circle"
android:layout_alignParentStart="true"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textStyle="italic"
android:textColor="#C0C0C0"
android:textSize="20sp"
android:id="@+id/tvStationName"
android:layout_toRightOf="@+id/circle"
android:layout_alignParentTop="true"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:layout_alignBottom="@+id/way"
android:gravity="top|start"
android:layout_marginLeft="5dp"/>
<ImageView
android:id="@+id/way"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_below="@+id/circle"
android:src="@drawable/white_way"/>
</RelativeLayout>
由于 ListFragment 表示一条路线,其中有车站(圆圈)和车站之间的道路(路),我不希望在最后一站之后出现道路。因此,我更改了最后一个 listview 元素的图像资源。问题如下:
如果我向下滚动列表,似乎一切正常。然后,滚动回顶部,如果它是列表的最后一个元素,则在两个中间站之间至少缺少一种方式。当我滚动更多时,我会得到更多丢失的方式,有时我会找回一些,这似乎是随机的。
适配器class的代码如下:
public class StationAdapter extends CursorAdapter {
private static final String TAG = "StationAdapter";
private Route route;
private Cursor storedCursor;
private LayoutInflater storedInflater;
private final class ViewHolder {
public TextView stationTv;
public ImageView stationIv;
public ImageView wayIv;
}
public StationAdapter(Context context, Cursor cursor, Route route) {
super(context, cursor, false);
this.route = route;
this.storedCursor = cursor;
this.storedInflater = LayoutInflater.from(context);
}
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
final LayoutInflater inflater = LayoutInflater.from(context);
View row = inflater.inflate(R.layout.station_list_row, null);
bindView(row, context, cursor);
return row;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (storedCursor.moveToPosition(position)) {
ViewHolder holder;
if (convertView == null) {
convertView = storedInflater.inflate(R.layout.station_list_row, null);
holder = new ViewHolder();
holder.stationTv = (TextView)convertView.findViewById(R.id.tvStationName);
holder.stationIv = (ImageView)convertView.findViewById(R.id.circle);
holder.wayIv = (ImageView)convertView.findViewById(R.id.way);
convertView.setTag(holder);
}
else {
holder = (ViewHolder)convertView.getTag();
}
Station station = DbLoader.getStationByCursor(storedCursor);
// now we use the references
holder.stationTv.setText(station.getName());
if (station.equals(route.lastStation())) {
holder.wayIv.setImageResource(R.drawable.zero_way);
}
}
return convertView;
}
@Override
public void bindView(View view, Context context, Cursor cursor) {
// UI elements
TextView stationTv = (TextView)view.findViewById(R.id.tvStationName);
ImageView wayIv = (ImageView)view.findViewById(R.id.way);
ImageView stationIv = (ImageView)view.findViewById(R.id.circle);
// station by cursor
Station station = DbLoader.getStationByCursor(cursor);
// set UI label
stationTv.setText(station.getName());
if (station.equals(route.lastStation())) {
wayIv.setImageResource(R.drawable.zero_way);
}
}
@Override
public Station getItem(int position) {
getCursor().moveToPosition(position);
return DbLoader.getStationByCursor(getCursor());
}
}
我不想引用太多细节,希望这些就足够了。
提前致谢。
问题是适配器试图提高效率。重用您滚动离开的视图。
如果您有条件更改视图的默认位置,则需要设置视图的默认位置。
例如,如果您更改背景图片。当该视图被回收时,它将在重复使用时使用相同的图像。
if (station.equals(route.lastStation())) {
holder.wayIv.setImageResource(R.drawable.zero_way);
}
例如,需要重置为默认值。
if (station.equals(route.lastStation())) {
holder.wayIv.setImageResource(R.drawable.zero_way);
} else {
holder.wayIv.setImageResource(R.drawable.white_way);
}