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

Android中如何在AsyncTask中展示自定义ProgressBar

问题原因

  • 构造参数错误:ProgressBar 构造函数的第四个参数接收的是样式资源ID,你传入的是布局文件ID,完全无法加载你定义的包含进度条和文本的自定义布局。
  • 视图类型不匹配:你定义的 custom_progress_bar.xml 根布局是 ConstraintLayout,不是 ProgressBar,用 ProgressBar 类型接收加载结果本身就会失效。
  • 布局参数缺少约束:你创建的 ConstraintLayout.LayoutParams 没有添加任何父布局约束,就算视图加载成功也不会出现在可见区域。

修复方案

修改 AsyncTask 相关代码,正确加载、添加自定义进度布局:

// 把原来的ProgressBar类型变量改为View类型,对应整个自定义布局
View progressLayout;

// 给AsyncTask指定泛型,第二个参数为进度值类型
public class LoadData extends AsyncTask<Void, Integer, Object> {

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        // 避免重复添加布局
        if (progressLayout != null && progressLayout.getParent() != null) {
            return;
        }
        // 加载自定义进度布局
        LayoutInflater inflater = LayoutInflater.from(MyActivity.this);
        progressLayout = inflater.inflate(R.layout.custom_progress_bar, null);
        
        ConstraintLayout rootCl = findViewById(R.id.constraintLayout);
        ConstraintLayout.LayoutParams lp = new ConstraintLayout.LayoutParams(
                ConstraintLayout.LayoutParams.MATCH_PARENT,
                ConstraintLayout.LayoutParams.MATCH_PARENT
        );
        // 添加约束让布局铺满父布局,内部进度条会自动居中
        lp.topToTop = ConstraintLayout.LayoutParams.PARENT_ID;
        lp.bottomToBottom = ConstraintLayout.LayoutParams.PARENT_ID;
        lp.startToStart = ConstraintLayout.LayoutParams.PARENT_ID;
        lp.endToEnd = ConstraintLayout.LayoutParams.PARENT_ID;
        progressLayout.setLayoutParams(lp);
        
        // 添加到根布局末尾,默认在Z轴最顶层
        rootCl.addView(progressLayout);
    }

    @Override
    protected Object doInBackground(Void... voids) {
        // 加载数据过程中如果要更新进度,调用publishProgress方法传入进度值
        // 例如加载到50%时:publishProgress(50);
        return null;
    }

    @Override
    protected void onProgressUpdate(Integer... values) {
        super.onProgressUpdate(values);
        if (progressLayout == null) return;
        int currentProgress = values[0];
        // 更新进度条和文本
        ProgressBar customBar = progressLayout.findViewById(R.id.customProgressBar);
        TextView progressText = progressLayout.findViewById(R.id.textViewProgress);
        customBar.setProgress(currentProgress);
        progressText.setText(currentProgress + " %");
    }

    @Override
    protected void onPostExecute(Object o) {
        // 任务结束后直接移除布局,避免残留
        if (progressLayout != null && progressLayout.getParent() != null) {
            ((ViewGroup) progressLayout.getParent()).removeView(progressLayout);
            progressLayout = null;
        }
    }
}

补充说明

  • 注意不要多次执行同一个AsyncTask实例,每次发起加载需要新建LoadData实例调用execute()方法。
  • 官方已废弃AsyncTask,长期来看推荐使用协程、WorkManager或者ThreadPoolExecutor替代异步任务实现。

内容的提问来源于stack exchange,提问作者MDNick2000

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 14:45:03