Search code examples
androidlistviewandroid-lazyadapter

Android. LazyAdapter is loading images incorrectly


I'm new to Android development. I'm trying to load several images to ListView using LazyAdapter. I store the images in the drawable folder. I have four images: image1.jpg, image2.jpg, image3.jpg and image4.jpg. But in the ListView they go in the following order: image1.jpg, image2.jpg, image1.jpg, image2.jpg. I tried to change the methods getItemId() and getItem() but it doesn't help to load all the images in the ListView, I still see only two of them. I cannot undestand what I'm doing wrong. Please refer to my code

public class MainActivityFragment extends Fragment {

CustomAdapter imagesAdapter;

public MainActivityFragment() {
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {

    int[] images = {R.drawable.image1,
            R.drawable.image2,
            R.drawable.image3,
            R.drawable.image4};

    imagesAdapter = new CustomAdapter(getActivity(), images);

    View rootView =  inflater.inflate(R.layout.fragment_main, container, false);
    ListView listView = (ListView) rootView.findViewById(R.id.listView);
    listView.setAdapter(imagesAdapter);

    return rootView;
}
}

Here is my LazyAdapter:

public class CustomAdapter extends BaseAdapter {

LayoutInflater inflater;
int[] imagePaths;

public CustomAdapter(Activity activity, int[] data) {
    imagePaths = data;
    inflater = (LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}

@Override
public int getCount() {
    return imagePaths.length;
}

@Override
public Object getItem(int position) {
    return position;
}

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

@Override
public View getView(int position, View convertView, ViewGroup parent) {

    View view = convertView;

    if(view == null) {

        view = inflater.inflate(R.layout.list_view_item, parent, false);
        ImageView imageView = (ImageView) view.findViewById(R.id.imageView);
        imageView.setImageResource(imagePaths[position]);
    }

    return view;
}

}

Please advice. How to make my code work correctly (i.e. to show all the images in the ListView, not only two of them)?


Solution

  • You are getting this behaviour because listview is designed in a way to re-use the items.

    @Override
    

    public View getView(int position, View convertView, ViewGroup parent) {

    View view = convertView;
    
    if(view == null) {
    
        view = inflater.inflate(R.layout.list_view_item, parent, false);
        ImageView imageView = (ImageView) view.findViewById(R.id.imageView);
        imageView.setImageResource(imagePaths[position]);
    }
    
    return view;
    

    }

    This code explains this. You are creating a view only if it is null, otherwise it will re-use the already created view.

    In your case, for items 1 and 2, the view was null so the adapter created new views and set the image resources correctly, but when you scrolled down to items 3 and 4, the adapter is using already created views, so it will show the previous images. As LuksProg suggested, you need to move setImageResource method outside the if clause, so that even when it is reusing the view, it will update it with new correct image.

    @Override
    

    public View getView(int position, View convertView, ViewGroup parent) {

    View view = convertView;
    
    if(view == null) {
    
        view = inflater.inflate(R.layout.list_view_item, parent, false);
        ImageView imageView = (ImageView) view.findViewById(R.id.imageView);
    }
    
        imageView.setImageResource(imagePaths[position]);
    
    return view;
    

    }