如何在带有文本的列表视图中显示从 API 下载的图像

Posted

技术标签:

【中文标题】如何在带有文本的列表视图中显示从 API 下载的图像【英文标题】:How to display image downloaded from API in listview with text 【发布时间】:2020-11-08 05:54:05 【问题描述】:

我有一个 ImageDownloader 类,用于从 API 下载图像,因为我已经测试在我的 activity_main.xml 文件中使用 ImageView 显示图像。我现在想在 Listview 中显示这些图像,以便它使用 listview_images.xml 布局为每个项目填充每个图像。我研究过需要一个自定义适配器文件来执行此操作,但是我对自定义适配器类非常不熟悉,我不确定在使用下载的图像时应该如何配置它们。

保存图像并从 ImageDownloaderService 获取图像并设置它的代码 - 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 类

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;
    

自定义适配器尝试

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;
    

【问题讨论】:

【参考方案1】:

使用这个库来显示图像

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

现在你的适配器

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;

【讨论】:

我是否需要更改 MainActivity 中的任何内容才能使其正常工作? 谢谢我让它工作只需将适配器设置为类。【参考方案2】:

您应该为上述内容使用回收站视图。

Check out this short tutorial on how to achieve the above

【讨论】:

以上是关于如何在带有文本的列表视图中显示从 API 下载的图像的主要内容,如果未能解决你的问题,请参考以下文章

在带有文本框的列表框中,如何关注添加的文本框?

如何遍历地图列表并在颤动列表视图中显示文本小部件?

从公共 API 获取 JSON 以在 SwiftUI 的列表视图中呈现

[IOS] - UITableView 与 UICollectionView API及其使用

如何在列表视图中为带有自动换行的可变多行长文本自动调整项目高度?

从列表视图中检索数据并将其显示在文本视图/图像视图中