androidxmllistviewimageviewcustom-adapter

How to display image downloaded from API in listview with text


I have an ImageDownloader class which is used to download images from the API which works as I have tested displaying the images with an ImageView in my activity_main.xml file. I now want to display these images within a Listview so that it populates each image for each item using listview_images.xml layout. I've researched that a custom adapter file is needed to do this however I am very unfamiliar with custom adapter classes and I am unsure how they should be configured when using a downloaded image.

Code to save image and get the image from ImageDownloaderService and set it - MainActvity

for (int i = 0; i < displayFilmsNowShowingServiceActivity.getResults().length(); i++) {
                    try {
                        //Store each film result as a JSONObject in the Array
                        films.add(displayFilmsNowShowingServiceActivity.getResults().getJSONObject(i));
                        JSONObject getResults = displayFilmsNowShowingServiceActivity.getResults().getJSONObject(i);
                        result[i] = getResults.getString("film_name");
                        filmID[i] = getResults.getString("film_id");
                        filmArt[i] = getResults.getJSONObject("images").getJSONObject("poster").getJSONObject("1").getJSONObject("medium").getString("film_image");
                        //Create a file to save the image to using the imdb id of the film as a file name
                        String imagePath = this.getDir("MyfilmLib", Context.MODE_PRIVATE).getAbsoluteFile() + "/MyFilmLib/" + filmID[i] + ".jpg";
                        File file = new File(imagePath);

                        //If the file already exists then just display the image
                        if (file.exists()) {
                            ivFilmArt.setImageBitmap(BitmapFactory.decodeFile(imagePath));
                        } else {
                            //If the file doesn't exist then create and use an ImageDownloadService to download the image and
                            //save it to file
                            ImageDownloadService imageDownloadService = new ImageDownloadService(filmArt[i], imagePath);
                            //Call the addListener() method (which ImageDownloadService inherits from AbstractService) and pass this activity as an argument.
                            //The ImageDownloadService object can then call the ServiceComplete() method in this activity once the web service call has finished
                            imageDownloadService.addListener(this);
                            //Put the ImageDownloadService object on a new thread
                            imageThread = new Thread(imageDownloadService);
                            //Start the thread which will automatically call the run() method in the ImageDownloadService object
                            imageThread.start();
                        }
                    } catch (JSONException ex) {
                        result[i] = "Error";
                        ex.printStackTrace();
                    }

                    lvFilms.setAdapter(new ArrayAdapter<>(this, R.layout.listview_images, R.id.tv_images_text, result));
                }

POJO Class

public class DisplayFilmsNowShowingPOJO {
    private int filmID;
    private String filmName;

    public DisplayFilmsNowShowingPOJO (int filmID, String filmName){
        this.filmID = filmID;
        this.filmName = filmName;
    }

    public int getFilmID() {
        return filmID;
    }

    public void setFilmID(int filmID) {
        this.filmID = filmID;
    }

    public String getFilmName() {
        return filmName;
    }

    public void setFilmName(String filmName) {
        this.filmName = filmName;
    }
}

Custom Adapter Attempt

public class DisplayFilmsNowShowingAdapter extends ArrayAdapter<DisplayFilmsNowShowingPOJO> {

    private Context mContext;
    private List<DisplayFilmsNowShowingPOJO> filmsList = new ArrayList<>();

    public DisplayFilmsNowShowingAdapter(@NonNull Context context, @LayoutRes ArrayList<DisplayFilmsNowShowingPOJO> list) {
        super(context, 0 , list);
        mContext = context;
        filmsList = list;
    }

    @NonNull
    @Override
    public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
        View listItem = convertView;
        if(listItem == null)
            listItem = LayoutInflater.from(mContext).inflate(R.layout.listview_images,parent,false);

        DisplayFilmsNowShowingPOJO currentFilm = filmsList.get(position);

        ImageView iv_art = (ImageView)listItem.findViewById(R.id.iv_art);
        iv_art.setImageResource(currentFilm.getFilmID());

        TextView name = (TextView) listItem.findViewById(R.id.tv_images_text);
        name.setText(currentFilm.getFilmName());

        return listItem;
    }
}

Solution

  • use this library for displaying image

      implementation 'com.github.bumptech.glide:glide:4.11.0'
      annotationProcessor 'com.github.bumptech.glide:compiler:4.11.0'
    

    now your adapter

    public class DisplayFilmsNowShowingAdapter extends ArrayAdapter<DisplayFilmsNowShowingPOJO> {
    
    private Context mContext;
    private List<DisplayFilmsNowShowingPOJO> filmsList = new ArrayList<>();
    
    public DisplayFilmsNowShowingAdapter(@NonNull Context context, @LayoutRes ArrayList<DisplayFilmsNowShowingPOJO> list) {
        super(context, 0 , list);
        mContext = context;
        filmsList = list;
    }
    
    @NonNull
    @Override
    public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
        View listItem = convertView;
        if(listItem == null)
            listItem = LayoutInflater.from(mContext).inflate(R.layout.listview_images,parent,false);
    
        DisplayFilmsNowShowingPOJO currentFilm = filmsList.get(position);
    
        ImageView iv_art = (ImageView)listItem.findViewById(R.id.iv_art);
    //        iv_art.setImageResource(currentFilm.getFilmID());
    
        Glide
             .with(iv_art.getContext())
             .load(currentFilm.getFilmID())
             .centerCrop()
             .into(iv_art );
    
        TextView name = (TextView) listItem.findViewById(R.id.tv_images_text);
        name.setText(currentFilm.getFilmName());
    
        return listItem;
    }
    

    }