带有CursorAdapter的Android ListView在滚动时工作错误

时间:2015-08-11 12:18:13

标签: android listview scroll android-cursoradapter

我已经阅读了几个小时的解决方案,但我仍然没有找到正确的答案。我有一个带有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元素的图像资源。问题如下:

如果我向下滚动列表,一切似乎都没问题。然后,滚动回到顶部,如果它是列表的最后一个元素,则两个中间站之间至少缺少一种方式。当我滚动更多时,我会得到更多缺失的方法,有时我会回来一些,它似乎是随机的。

适配器类的代码如下:

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

我不想引用太多细节,我希望这已经足够了。

提前致谢。

1 个答案:

答案 0 :(得分:0)

问题是适配器试图提高效率。重用已滚动的视图。

如果您的条件更改了默认值,则需要设置视图的默认位置。

因此,例如,如果您更改背景图像。当该视图被回收时,它将在重用时使用相同的图像。

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