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

Firebase子节点狗狗数据检索及构造类绑定TextView显示的实现问题

问题根因说明

  1. 空指针报错的直接原因:XML布局中age、weight、gender、neutered均为Spinner类型,你在Java代码中将其声明为TextView,类型不匹配导致控件初始化失败。
  2. 无法调用Dog类get/set方法的原因:你没有将Firebase返回的DataSnapshot转换成Dog类实例,而是手动逐个读取字段,自然无法调用类方法。
  3. 多只狗场景下的逻辑漏洞:你当前遍历所有狗狗节点时直接给同一组控件赋值,最终页面只会显示最后一只狗的信息,无法区分展示不同狗狗的数据。

多只狗狗场景最优实现方案

  • 存储层优化:不建议用狗狗名称作为节点ID,仍然使用Firebase push()生成的唯一字符串作为狗狗节点ID,将名称作为Dog类的普通字段存储,避免重名狗狗数据被覆盖。
  • 交互层设计:在DogProfile页面顶部新增一个狗狗选择Spinner,加载当前用户所有狗狗的名称,用户选中对应狗狗后再刷新页面展示的信息。

代码修改实现

1. 布局XML新增狗狗选择Spinner

在你现有的XML布局的顶部新增如下控件:

<Spinner
    android:id="@+id/dogSelector"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:hint="选择要查看的狗狗"
    app:layout_constraintTop_toTopOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    android:layout_margin="16dp"/>

同时修正你现有控件的使用逻辑:age、weight等为Spinner类型,后续赋值需要调用setSelection()方法,或者如果你只需要展示不需要选择,直接把XML里的Spinner改成TextView即可。

2. 修正DogProfile类逻辑

public class DogProfile extends AppCompatActivity {

    private FirebaseAuth firebaseAuth;
    private FirebaseUser currentUser;

    // 修正控件类型,如果不需要选择直接改成TextView
    TextView breed;
    Spinner age, dogGender, weight, isNeutered, dogSelector;
    String uid;
    List<Dog> dogList = new ArrayList<>();
    List<String> dogKeyList = new ArrayList<>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.dog_profile);

        firebaseAuth = FirebaseAuth.getInstance();
        currentUser = firebaseAuth.getCurrentUser();
        if(currentUser == null) {
            // 处理未登录逻辑,避免空指针
            finish();
            return;
        }
        uid = currentUser.getUid();

        // 初始化控件
        dogSelector = findViewById(R.id.dogSelector);
        breed = findViewById(R.id.breed);
        age = findViewById(R.id.age);
        dogGender = findViewById(R.id.gender);
        weight = findViewById(R.id.weight);
        isNeutered = findViewById(R.id.neutered);

        DatabaseReference databaseReference = FirebaseDatabase.getInstance("你的数据库地址").getReference("user").child(uid).child("dogs");

        databaseReference.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {
                dogList.clear();
                dogKeyList.clear();
                List<String> dogNameList = new ArrayList<>();
                for (DataSnapshot ds : dataSnapshot.getChildren()) {
                    // 直接转换为Dog对象,即可调用get方法
                    Dog dog = ds.getValue(Dog.class);
                    if(dog != null) {
                        dogList.add(dog);
                        dogKeyList.add(ds.getKey());
                        dogNameList.add(dog.getName());
                    }
                }
                // 把狗狗名称加载到选择器
                ArrayAdapter<String> adapter = new ArrayAdapter<>(DogProfile.this, android.R.layout.simple_spinner_dropdown_item, dogNameList);
                dogSelector.setAdapter(adapter);

                // 选择狗狗后刷新展示信息
                dogSelector.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
                    @Override
                    public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                        Dog selectedDog = dogList.get(position);
                        breed.setText(selectedDog.getBreed());
                        // 这里Spinner赋值需要根据你配置的选项列表设置对应position,若只是展示建议改成TextView直接setText
                        // age.setSelection(xxx);
                        // 其他属性同理调用get方法获取
                    }

                    @Override
                    public void onNothingSelected(AdapterView<?> parent) {

                    }
                });
            }

            @Override
            public void onCancelled(DatabaseError databaseError) {
                Log.w("TAG", "onCancelled", databaseError.toException());
            }
        });
    }
}

特定狗狗信息直接查询方法

如果你需要从其他页面跳转到DogProfile直接展示指定狗狗的信息,只需要在跳转时通过Intent传递狗狗的节点ID,在DogProfile中直接查询对应节点即可,不需要遍历所有狗狗:

// 跳转时传参
Intent intent = new Intent(this, DogProfile.class);
intent.putExtra("dogId", "目标狗狗的节点ID");
startActivity(intent);

// DogProfile中接收参数直接查询
String dogId = getIntent().getStringExtra("dogId");
DatabaseReference dogRef = FirebaseDatabase.getInstance("你的数据库地址").getReference("user").child(uid).child("dogs").child(dogId);
// 直接监听这个节点的变化即可

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.10 11:48:01