GridView recycles child view that is still visible

51 views Asked by At

I have a GridView that is recycling child views using an adapter. Each child view is composed of an ImageView with a TextView overlayed on top. The problem I'm seeing is that as I scroll and new images come into view, the image of other cells in the grid can also change to the images that are coming into view.

After debugging I can see that this is because when a new row comes into view, getView() is called on the adapter to get the view for the new row. However the view being passed into the method, that android wants me to recycle, is actually still in view. So when I update the image of the view it gives me, I end up changing the image of another item in the grid too.

Does anyone know what could cause this?

Activity

<android.support.v4.widget.SwipeRefreshLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/snapshot_list_swipe_refresh"
android:layout_width="match_parent"
android:layout_height="match_parent">

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_snapshot_list"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.vellocet.snapshotviewer.SnapshotListActivity">

    <GridView
        android:id="@+id/snapshot_grid"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_margin="5dp"
        android:drawSelectorOnTop="true"
        android:gravity="center"
        android:numColumns="2"
        android:stretchMode="columnWidth"
        android:verticalSpacing="0dp"
        android:horizontalSpacing="0dp"
        android:focusable="true"
        android:clickable="true"/>

</RelativeLayout>

</android.support.v4.widget.SwipeRefreshLayout>

Adapter:

private class SnapshotListAdapter extends BaseAdapter {
    private final Context context;
    private List<Snapshot> snapshots;

    public SnapshotListAdapter(Context context, List<Snapshot> snapshots) {
        this.context = context;
        snapshots = snapshots;
    }

    @Override
    public int getCount() {
        return snapshots.size();
    }

    @Override
    public Object getItem(int i) {
        return i < snapshots.size() ? snapshots.get(i) : null;
    }

    @Override
    public long getItemId(int i) {
        return i;
    }

    @Override
    public View getView(int i, View view, ViewGroup viewGroup) {
        ViewHolder viewHolder;

        if (view == null) {
            LayoutInflater inflater = ((Activity)context).getLayoutInflater();
            view = inflater.inflate(R.layout.snapshot_grid_item_layout, viewGroup, false);
            viewHolder = new ViewHolder();
            viewHolder.image = (ImageView)view.findViewById(R.id.snapshot_grid_item_imageview);
            viewHolder.text = (TextView) view.findViewById(R.id.snapshot_grid_item_textview);
            view.setTag(viewHolder);

            view.setLayoutParams(new GridView.LayoutParams(
                    GridView.LayoutParams.MATCH_PARENT,
                    (int)getResources().getDimension(R.dimen.snapshot_grid_item_height)));
        }
        else {
            viewHolder = (ViewHolder)view.getTag();
        }

        final Snapshot snapshot = snapshots.get(i);
        viewHolder.snapshot = snapshot;
        viewHolder.image.setImageDrawable(null);
        viewHolder.updateText();

        snapshot.getSnapshotFiles(new GetSnapshotCallback(viewHolder, snapshot));

        return view;
    }
}

Thanks for any help

1

There are 1 answers

0
dco123 On

My mistake. Although a view that is still on screen is being recycled, a new view is subsequently created for the original position.

E.g If position 0 is on screen and you scroll to bring position 8 into view, the view for position 0 is recycled into position 8 even though position 0 is still on screen. However it will then call another createView for position 0, passing in no recycle view, so a new instance is created. Slightly odd process but it's not causing the problem i'm seeing with images appearing in multiple image views.