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

Firebase数据无法在App启动时显示于HomeFragment的问题

问题描述

我希望将Firebase数据库中的用户名展示在HomeFragment中。当前在MainActivity中从Firebase获取数据后传递给目标Fragment,但App启动时Fragment不显示数据库数据,切换其他Fragment再返回后才会显示。

MainActivity 代码

package com.shariarunix.examiner;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;

import android.annotation.SuppressLint;
import android.os.Bundle;
import android.util.Log;
import android.view.MenuItem;
import android.widget.Toast;

import com.google.android.material.bottomnavigation.BottomNavigationView;
import com.google.android.material.navigation.NavigationBarView;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;

import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity {
    private String uniqueKey;
    private String userName, userEmail, userPhone, userCourse;
    List<StudentDataModel> sDataList = new ArrayList<>();
    BottomNavigationView navBottom;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        // Default Fragment
        loadFrag(HomeFragment.getInstance(userName, userCourse), 0);
        Toast.makeText(MainActivity.this, ""+userName+" : "+userCourse, Toast.LENGTH_SHORT).show();
        // Add Operation on Bottom Navigation Bar
        navBottom = findViewById(R.id.nav_bar);
        navBottom.getMenu().findItem(R.id.home).setChecked(true);
        navBottom.setOnItemSelectedListener(new NavigationBarView.OnItemSelectedListener() {
            @SuppressLint("NonConstantResourceId")
            @Override
            public boolean onNavigationItemSelected(@NonNull MenuItem item) {
                switch (item.getItemId()){
                    case R.id.profile:
                        // Loading Profile Fragment
                        loadFrag(new ProfileFragment(), 1);
                        break;
                    case R.id.home:
                        // Load Home Fragment
                        loadFrag(HomeFragment.getInstance(userName,userCourse), 1);
                        break;
                    case R.id.resource:
                        // Load R
                        loadFrag(new ResourceFragment(sDataList), 1);
                        Toast.makeText(MainActivity.this, "Resource", Toast.LENGTH_SHORT).show();
                        break;
                    default:
                        Toast.makeText(MainActivity.this, "Bonk", Toast.LENGTH_SHORT).show();
                }
                return true;
            }
        });
    }
    //Swapping Fragment
    public void loadFrag(Fragment fragment, int flag){
        FragmentManager fragManager = getSupportFragmentManager();
        FragmentTransaction fragTrans = fragManager.beginTransaction();

        if (flag == 0){
            fragTrans.add(R.id.fragment_frame, fragment);
        }else{
            fragTrans.replace(R.id.fragment_frame, fragment);
        }
        fragTrans.commit();
    }
    // Load Data from database
    public void loadData(){
        DatabaseReference mDatabase = FirebaseDatabase.getInstance().getReference();
        mDatabase.child("Student's Data").child(uniqueKey).addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot snapshot) {
                sDataList.clear();
                StudentDataModel sData = snapshot.getValue(StudentDataModel.class);
                assert sData != null;
                userName = sData.getName();
                userEmail = sData.getEmail();
                userPhone = sData.getPhone();
                userCourse = sData.getCourse();
                sDataList.add(sData);
            }

            @Override
            public void onCancelled(@NonNull DatabaseError error) {
                Toast.makeText(MainActivity.this, "Hoy nai", Toast.LENGTH_SHORT).show();
            }
        });
    }
    @Override
    protected void onStart() {
        super.onStart();
        uniqueKey = getIntent().getStringExtra("uniqueKey");
        loadData();
    }
}

HomeFragment 代码

package com.shariarunix.examiner;

import android.content.Intent;
import android.os.Bundle;

import androidx.appcompat.widget.AppCompatButton;
import androidx.fragment.app.Fragment;

import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import java.util.ArrayList;
import java.util.List;

public class HomeFragment extends Fragment {
    private static final String U_NAME = "uName";
    private static final String U_COURSE = "uCourse";
    private String uName, uCourse;
    public HomeFragment(){
        //Default Empty Constructor
    }
    public static HomeFragment getInstance(String uName, String uCourse){
        HomeFragment homeFragment = new HomeFragment();

        Bundle bundle = new Bundle();
        bundle.putString(U_NAME, uName);
        bundle.putString(U_COURSE, uCourse);

        homeFragment.setArguments(bundle);

        return homeFragment;
    }
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_home, container, false);

        TextView txtShowName = view.findViewById(R.id.txt_show_name_home);

        AppCompatButton btnExamReadMore = view.findViewById(R.id.btn_exam_read_more);

        if (getArguments()!= null){
            uName = getArguments().getString(U_NAME);
            uCourse = getArguments().getString(U_COURSE);
        }
        txtShowName.setText(uName);

        btnExamReadMore.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                startActivity(new Intent(getActivity(), ExamInfoActivity.class));
            }
        });
        return view;
    }
}

问题原因

Firebase数据获取是异步操作:

  1. App启动时,onCreate方法先加载了HomeFragment,但此时loadData还在后台请求数据,userName和userCourse都是空值
  2. 切换Fragment返回时,Firebase已经完成数据加载,userName已有有效值,所以Fragment能正常显示内容

解决方案

方案一:Activity控制数据加载后更新Fragment

通过保留Fragment引用,在Firebase数据加载完成后初始化或更新Fragment的UI:

修改后的MainActivity代码

package com.shariarunix.examiner;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;

import android.annotation.SuppressLint;
import android.os.Bundle;
import android.view.MenuItem;
import android.widget.Toast;

import com.google.android.material.bottomnavigation.BottomNavigationView;
import com.google.android.material.navigation.NavigationBarView;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;

import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity {
    private String uniqueKey;
    private String userName, userEmail, userPhone, userCourse;
    List<StudentDataModel> sDataList = new ArrayList<>();
    BottomNavigationView navBottom;
    private HomeFragment homeFragment; // 保留Fragment引用

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        // 初始化底部导航
        navBottom = findViewById(R.id.nav_bar);
        navBottom.getMenu().findItem(R.id.home).setChecked(true);
        navBottom.setOnItemSelectedListener(new NavigationBarView.OnItemSelectedListener() {
            @SuppressLint("NonConstantResourceId")
            @Override
            public boolean onNavigationItemSelected(@NonNull MenuItem item) {
                switch (item.getItemId()){
                    case R.id.profile:
                        loadFrag(new ProfileFragment(), 1);
                        break;
                    case R.id.home:
                        homeFragment = HomeFragment.getInstance(userName,userCourse);
                        loadFrag(homeFragment, 1);
                        break;
                    case R.id.resource:
                        loadFrag(new ResourceFragment(sDataList), 1);
                        Toast.makeText(MainActivity.this, "Resource", Toast.LENGTH_SHORT).show();
                        break;
                    default:
                        Toast.makeText(MainActivity.this, "Bonk", Toast.LENGTH_SHORT).show();
                }
                return true;
            }
        });
    }

    public void loadFrag(Fragment fragment, int flag){
        FragmentManager fragManager = getSupportFragmentManager();
        FragmentTransaction fragTrans = fragManager.beginTransaction();

        if (flag == 0){
            fragTrans.add(R.id.fragment_frame, fragment);
        }else{
            fragTrans.replace(R.id.fragment_frame, fragment);
        }
        fragTrans.commit();
    }

    public void loadData(){
        DatabaseReference mDatabase = FirebaseDatabase.getInstance().getReference();
        mDatabase.child("Student's Data").child(uniqueKey).addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot snapshot) {
                sDataList.clear();
                StudentDataModel sData = snapshot.getValue(StudentDataModel.class);
                assert sData != null;
                userName = sData.getName();
                userEmail = sData.getEmail();
                userPhone = sData.getPhone();
                userCourse = sData.getCourse();
                sDataList.add(sData);

                // 数据加载完成后初始化或更新Fragment
                if (homeFragment == null) {
                    homeFragment = HomeFragment.getInstance(userName, userCourse);
                    loadFrag(homeFragment, 0);
                } else {
                    homeFragment.updateUserInfo(userName, userCourse);
                }
                
                Toast.makeText(MainActivity.this, ""+userName+" : "+userCourse, Toast.LENGTH_SHORT).show();
            }

            @Override
            public void onCancelled(@NonNull DatabaseError error) {
                Toast.makeText(MainActivity.this, "Hoy nai", Toast.LENGTH_SHORT).show();
            }
        });
    }

    @Override
    protected void onStart() {
        super.onStart();
        uniqueKey = getIntent().getStringExtra("uniqueKey");
        loadData();
    }
}

修改后的HomeFragment代码

添加UI更新方法,供Activity调用:

package com.shariarunix.examiner;

import android.content.Intent;
import android.os.Bundle;

import androidx.appcompat.widget.AppCompatButton;
import androidx.fragment.app.Fragment;

import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import java.util.ArrayList;
import java.util.List;

public class HomeFragment extends Fragment {
    private static final String U_NAME = "uName";
    private static final String U_COURSE = "uCourse";
    private String uName, uCourse;
    private TextView txtShowName; // 保留TextView引用

    public HomeFragment(){
        //Default Empty Constructor
    }

    public static HomeFragment getInstance(String uName, String uCourse){
        HomeFragment homeFragment = new HomeFragment();

        Bundle bundle = new Bundle();
        bundle.putString(U_NAME, uName);
        bundle.putString(U_COURSE, uCourse);

        homeFragment.setArguments(bundle);

        return homeFragment;
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_home, container, false);

        txtShowName = view.findViewById(R.id.txt_show_name_home);
        AppCompatButton btnExamReadMore = view.findViewById(R.id.btn_exam_read_more);

        if (getArguments()!= null){
            uName = getArguments().getString(U_NAME);
            uCourse = getArguments().getString(U_COURSE);
            txtShowName.setText(uName);
        }

        btnExamReadMore.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                startActivity(new Intent(getActivity(), ExamInfoActivity.class));
            }
        });
        return view;
    }

    // 供Activity调用的UI更新方法
    public void updateUserInfo(String name, String course) {
        this.uName = name;
        this.uCourse = course;
        if (txtShowName != null) {
            txtShowName.setText(uName);
        }
    }
}

方案二:Fragment自主监听Firebase数据(解耦性更好)

让Fragment直接获取并监听Firebase数据,无需Activity传递:

@Override
public void onStart() {
    super.onStart();
    if (getActivity() != null) {
        String uniqueKey = getActivity().getIntent().getStringExtra("uniqueKey");
        DatabaseReference mDatabase = FirebaseDatabase.getInstance().getReference();
        mDatabase.child("Student's Data").child(uniqueKey).addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot snapshot) {
                StudentDataModel sData = snapshot.getValue(StudentDataModel.class);
                if (sData != null) {
                    txtShowName.setText(sData.getName());
                }
            }

            @Override
            public void onCancelled(@NonNull DatabaseError error) {
                Toast.makeText(getActivity(), "加载失败", Toast.LENGTH_SHORT).show();
            }
        });
    }
}

方案对比
  • 方案一:适合需要在多个Fragment共享同一数据的场景,由Activity统一管理数据
  • 方案二:Fragment自主管理数据,解耦性更强,适合单个Fragment独立使用数据的场景

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 23:38:13