如何在不重新加载 Android 中的图像的情况下更新 Recyclerview 中的项目

问题描述

在 Recyclerview 中,有许多具有图像的项目。用户想要下载所需的图像,但是当所需的项目必须更新以显示下载的百分比时,问题是当所需的百分比向用户显示他想要重新加载照片时,但我只想要 {{ 1}} 字段要更新。

如下图,用户点击图片进行下载,但是在编辑下载百分比时,图片不断重新加载,但我想要的是加载一次图片,只编辑Progress ,例如在 TelegramWhatsapp 中下载图片

enter image description here

在适配器中:

Progress

要更改活动进度,我只需调用方法

public class Adpnotice extends RecyclerView.Adapter<Adpnotice.ViewHolder> {

private List<Notice> ITEMS = new ArrayList<>();

public Adpnotice() {
    
}

public void AddItem(Notice item) {
    ITEMS.add(item);
    notifyDataSetChanged();
}

public void SetProgressMessage(double messageId,int progress) {
    int i = 0;
    for (Notice item : ITEMS) {
        if (item.MessageId == messageId) {
            item.Progress = progress;
            item.DownloadStatus = "Downloading";
            break;
        }
        ++i;
    }
    notifyItemChanged(i,"CHANGE_PROGRESS");
}

@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup,int i) {
    View view = LayoutInflater.from(AppController.Context)
                    .inflate(R.layout.item_notice_image,viewGroup,false);
           
    return new ViewHolder(view);
}

@Override
public void onBindViewHolder(@NonNull ViewHolder viewNotice,int i) {
    Notice item = GetItem(i);

    
            switch (item.DownloadStatus) {
                case "Downloaded":
                    
                    viewNotice.tvDownloading.setVisibility(View.GONE);
                    viewNotice.tvTotalSize.setVisibility(View.GONE);
                    AppController.SetPicFile(viewNotice.imgRow,new File(item.DirectoryPath + item.FileName),"");
                    
                    break;
                case "Downloading":
                    
                    viewNotice.tvTotalSize.setVisibility(View.VISIBLE);
                    viewNotice.tvDownloading.setVisibility(View.VISIBLE);
                    
                    viewNotice.tvDownloading.setText(item.Progress + "%");
                    break;
                case "NotDownloaded":
                    
                    viewNotice.tvDownloading.setVisibility(View.GONE);
                    viewNotice.tvTotalSize.setVisibility(View.VISIBLE);

                    AppController.SetPicUrl(viewNotice.imgRow,item.FilePath,"");
                    break;
            }
            viewNotice.tvTotalSize.setText(item.FileSize);
            viewNotice.tvDate.setText(item.Date);
            AppController.SetPicDrawable(viewNotice.imgDownload,R.drawable.download_file,"");
            
}

@Override
public void onBindViewHolder(@NonNull ViewHolder holder,int position,@NonNull List<Object> payloads) {
    boolean found = false;
    for (Object payLoad : payloads) {
        if (payLoad.equals("CHANGE_PROGRESS")) {
            found = true;
            break;
        }
    }
    if (found) {
        super.onBindViewHolder(holder,position,payloads);
    } else {
        onBindViewHolder(holder,position);
    }
}

@Override
public int getItemCount() {
    return ITEMS.size();
}

public class ViewHolder extends RecyclerView.ViewHolder {

    @BindView(R.id.tvDate)
    TextView tvDate;
    @BindView(R.id.tvText)
    @Nullable
    TextView tvText;
    @BindView(R.id.imgRow)
    @Nullable
    ImageView imgRow;

    //ImageLayout
    @BindView(R.id.tvTotalSize)
    @Nullable
    TextView tvTotalSize;
    @BindView(R.id.imgDownload)
    @Nullable
    ImageView imgDownload;
    @BindView(R.id.tvDownloading)
    @Nullable
    TextView tvDownloading;
    @BindView(R.id.layoutLoading)
    @Nullable
    RelativeLayout layoutLoading;

    public ViewHolder(@NonNull View itemView) {
        super(itemView);
        ButterKnife.bind(this,itemView);
    }
}
}

解决方法

在方法 SetProgressMessage 中,您应该使用带有负载的 notifyItemChanged API。


// use notifyItemChanged with payload
public void SetProgressMessage(double messageId,int progress) {
    int i = 0;
    ...
    notifyItemChanged(i,"PROGRESS");
}

// override onBindViewHolder with payloads parameters
public void onBindViewHolder(@NonNull ViewHolder holder,int position,@NonNull List<Object> payloads) {
    boolean found = false;
    for(payload in playloads) {
        if(payload == "PROGRESS"){
            found = true
            // just update progress 
        }
    }
    if(found) {
        super.onBindViewHolder(holder,position,payloads);
    }
}