You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android Adapter中ProgressBar更新异常:进度条直接拉满问题求助

问题分析与解决方案

核心问题原因

  1. ProgressBar配置错误:XML中android:max="1",而你将进度值(0.17、0.35…1.0)直接转成Int后,只有0或1两个值,导致进度条直接从0跳到1(拉满),无法显示中间进度。
  2. Adapter进度更新方式错误:全局holderCallback的设计不符合RecyclerView的ViewHolder复用机制,每次进度更新都覆盖回调,且无法精准定位到当前上传的item,容易出现复用混乱。

分步解决方案

1. 修正ProgressBar配置

修改XML中ProgressBar的max属性为100,用百分比表示进度:

<ProgressBar
    android:id="@+id/progress_file_uploading"
    style="@style/Widget.AppCompat.ProgressBar.Horizontal"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:max="100" />

2. 调整文件数据模型

给文件数据类添加进度字段,存储当前上传的百分比进度:

data class FileItem(
    // 原有字段:文件名、路径等
    val fileName: String,
    val filePath: String,
    // 新增进度字段
    var progress: Int = 0
)

3. 重构Adapter逻辑

去掉全局holderCallback,改为在ViewHolder的bind方法中直接根据数据更新进度:

class FileListAdapter(private val fileList: MutableList<FileItem>) : RecyclerView.Adapter<FileListAdapter.FileViewHolder>() {

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): FileViewHolder {
        val view = LayoutInflater.from(parent.context).inflate(R.layout.item_file, parent, false)
        return FileViewHolder(view)
    }

    override fun onBindViewHolder(holder: FileViewHolder, position: Int) {
        holder.bind(fileList[position])
    }

    override fun getItemCount() = fileList.size

    class FileViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
        private val progressBar: ProgressBar = itemView.findViewById(R.id.progress_file_uploading)

        fun bind(fileItem: FileItem) {
            // 绑定其他UI数据(如文件名)
            // 更新进度条
            progressBar.progress = fileItem.progress
        }
    }
}

4. 修正Fragment中的进度更新逻辑

在进度回调中计算百分比进度,更新对应数据项的进度值后,通知Adapter刷新对应位置的UI(注意要在主线程执行UI更新):

// 假设当前上传的文件在fileList中的位置为position
val countingRequestBody = CountingRequestBody(it) { bytesWritten, contentLength ->
    val progressPercent = (1.0 * bytesWritten / contentLength * 100).toInt()
    println("Written: $progressPercent%")

    // 切换到主线程更新数据和UI
    requireActivity().runOnUiThread {
        // 更新对应文件的进度
        fileList[position].progress = progressPercent
        // 通知Adapter刷新该位置的item
        fileAdapter.notifyItemChanged(position)
    }
}

额外注意事项

  • 确保CountingRequestBody的进度回调如果在子线程执行,必须切换到主线程再更新UI,否则会抛出异常。
  • 如果文件列表有排序或刷新操作,要保证position始终对应正确的上传文件,避免更新错误的item。

内容的提问来源于stack exchange,提问作者Mehmet Gür

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 08:27:36