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

Android Firebase数据加载完成后ProgressBar无法隐藏问题

问题原因

你的ProgressBar加载完成后无法隐藏是两个核心错误导致的:

  • 控件查找逻辑位置错误:你的ProgressBar定义在Activity的根布局中,但你在RecyclerView子项的ViewHolder中调用itemView.findViewById(R.id.progress_bar)查找控件,itemView对应的是列表单个条目布局circular_item,这个布局里根本没有id为progress_bar的控件,所以适配器里的progressBar变量始终为null,后续的隐藏逻辑永远不会触发。
  • 职责划分错误:适配器只负责管理RecyclerView子项的视图渲染,不应该直接操作Activity层级的全局加载控件,这种写法耦合度高,很容易出现空指针问题。
修复步骤

1. 清理适配器中的无效代码

打开CAdapter.java,删除所有和ProgressBar相关的错误代码:

  • 删除类成员变量声明ProgressBar progressBar;
  • 删除myViewHolder构造方法中的progressBar = itemView.findViewById(R.id.progress_bar);
  • 删除原来写在适配器中的onDataChanged()方法里操作progressBar的逻辑

清理后适配器核心代码结构如下:

public class CAdapter extends FirebaseRecyclerAdapter<Cmodel,CAdapter.myViewHolder> {

    public CAdapter(@NonNull FirebaseRecyclerOptions<Cmodel> options) {
        super(options);
    }

    @Override
    protected void onBindViewHolder(@NonNull myViewHolder holder, int position, @NonNull Cmodel model) {
        holder.Cdate.setText(model.getCdate());
        holder.Cheading.setText(model.getCheading());
        holder.Cbody.setText(model.getCbody());
    }

    @NonNull
    @Override
    public myViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.circular_item,parent,false);
        return new myViewHolder(view);
    }

    class myViewHolder extends RecyclerView.ViewHolder{
        TextView Cdate,Cheading,Cbody,Ndate,Nheading,Nsheading,Nbody,Tdate,Tsubject,Ttopic,Ttdate;
        public myViewHolder(@NonNull View itemView) {
            super(itemView);
            Cdate = itemView.findViewById(R.id.cdate);
            Cheading = itemView.findViewById(R.id.cheading);
            Cbody = itemView.findViewById(R.id.cbody);
        }
    }
}

2. 在Activity中实现加载完成隐藏逻辑

把ProgressBar的控制逻辑放到对应的Activity(你的布局中tools:context配置的是.CircularAct)中处理:

  1. 在Activity中初始化ProgressBar控件
  2. 给适配器注册数据变化监听,数据加载完成后隐藏ProgressBar
  3. 正确管理Firebase适配器的监听生命周期

参考代码如下:

public class CircularAct extends AppCompatActivity {
    private ProgressBar progressBar;
    private CAdapter adapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main); // 替换为你实际的布局文件名

        // 初始化控件
        RecyclerView rv = findViewById(R.id.rv);
        progressBar = findViewById(R.id.progress_bar);

        // 配置Firebase查询选项(替换为你自己的查询逻辑)
        FirebaseRecyclerOptions<Cmodel> options = new FirebaseRecyclerOptions.Builder<Cmodel>()
                .setQuery(/* 你的Firebase Database查询引用 */, Cmodel.class)
                .build();

        adapter = new CAdapter(options);
        rv.setLayoutManager(new LinearLayoutManager(this)); // 必须给RecyclerView设置LayoutManager,否则列表不会显示
        rv.setAdapter(adapter);

        // 监听数据加载状态
        adapter.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() {
            @Override
            public void onChanged() {
                super.onChanged();
                progressBar.setVisibility(View.GONE);
            }
        });
    }

    @Override
    protected void onStart() {
        super.onStart();
        adapter.startListening(); // 开始监听Firebase数据变化
    }

    @Override
    protected void onStop() {
        super.onStop();
        adapter.stopListening(); // 页面不可见时停止监听,避免内存泄漏
    }
}

可选方案:如果要在适配器内处理隐藏逻辑

如果不想在Activity里写监听,可以给适配器增加构造方法,把Activity里的ProgressBar实例传进来,再重写onDataChanged方法:

// 适配器修改构造方法
public class CAdapter extends FirebaseRecyclerAdapter<Cmodel,CAdapter.myViewHolder> {
    private ProgressBar progressBar;

    public CAdapter(@NonNull FirebaseRecyclerOptions<Cmodel> options, ProgressBar progressBar) {
        super(options);
        this.progressBar = progressBar;
    }

    // 其他onCreateViewHolder、onBindViewHolder、ViewHolder代码不变,重写onDataChanged
    @Override
    public void onDataChanged() {
        super.onDataChanged();
        if (progressBar != null) {
            progressBar.setVisibility(View.GONE);
        }
    }
}

然后在Activity初始化适配器的时候传入progressBar实例即可:
adapter = new CAdapter(options, progressBar);

更推荐把视图控制逻辑放在Activity中,避免适配器持有控件引用导致的内存泄漏风险。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 13:15:35