Android 显示特定于Firebase的子级';在ListView中创建数组项

Android 显示特定于Firebase的子级';在ListView中创建数组项,android,firebase,firebase-realtime-database,Android,Firebase,Firebase Realtime Database,我有一个python脚本,可以在firebase上实时添加数据。 该脚本使用摄像头检测冰箱中有哪些食物,并添加找到的食物。 我想构建一个android应用程序,获取最新数据(即网络摄像头最近的检测结果) 例如,在下图中,最后一次食品检测是酸奶,之前的检测是酸奶和鸡蛋 我使用以下代码在列表视图中显示可用食物 rv = (ListView) findViewById(R.id.myrv); ref = FirebaseDatabase.getInstance().getReference();

我有一个python脚本,可以在firebase上实时添加数据。 该脚本使用摄像头检测冰箱中有哪些食物,并添加找到的食物。 我想构建一个android应用程序,获取最新数据(即网络摄像头最近的检测结果)

例如,在下图中,最后一次食品检测是
酸奶
,之前的检测是
酸奶
鸡蛋

我使用以下代码在
列表视图中显示可用食物

rv = (ListView) findViewById(R.id.myrv);
ref = FirebaseDatabase.getInstance().getReference();

final ArrayAdapter<String> adpt = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, foodList);
rv.setAdapter(adpt);

ref.child("fridge").orderByKey().limitToLast(1).addChildEventListener(new ChildEventListener() {
    @Override
    public void onChildAdded(DataSnapshot dataSnapshot, String s) {
        String message = dataSnapshot.getValue(String.class);
        foodList.add(message);
        adpt.notifyDataSetChanged();
    }

    @Override
    public void onChildChanged(DataSnapshot dataSnapshot, String s) {

    }

    @Override
    public void onChildRemoved(DataSnapshot dataSnapshot) {

    }

    @Override
    public void onChildMoved(DataSnapshot dataSnapshot, String s) {

    }

    @Override
    public void onCancelled(DatabaseError databaseError) {

    }
});
我想知道对于最近的
key
,这是否是获取
food
中内容的正确代码,以及如何修复
hashmap
错误

谢谢

这里:

String message = dataSnapshot.getValue(String.class);
可能会导致此问题,因为您似乎将
String.class
hashmap设置为
String

试着这样做:

Map<String, Object> map = (Map<String, Object>) dataSnapshot.getValue();
编辑#2:

也可以通过添加另一个孩子(
食物
):

用你的第一个结构

使用
runOnUiThread()
方法,然后通知数据更改等以影响UI。

这是我最终得到的解决方案,以防有人需要它

food = (TextView) findViewById(R.id.food);
        rv = (ListView) findViewById(R.id.myrv);
        ref = FirebaseDatabase.getInstance().getReference().child("fridge2");
        final ArrayAdapter<String> adpt = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, myfoodList);
        rv.setAdapter(adpt);

        ref.orderByKey().limitToLast(1).addChildEventListener(new ChildEventListener() {
            @Override
            public void onChildAdded(DataSnapshot dataSnapshot, String s) {
               // ArrayList message = dataSnapshot.getValue(ArrayList.class);

                GenericTypeIndicator<List<String>> t = new GenericTypeIndicator<List<String>>() {};
                List<String> message = dataSnapshot.getValue(t);

                myfoodList.clear();
                myfoodList.addAll(message);

                //myfoodList = message;
                adpt.notifyDataSetChanged();
            }
food=(TextView)findViewById(R.id.food);
rv=(列表视图)findViewById(R.id.myrv);
ref=FirebaseDatabase.getInstance().getReference().child(“fridge2”);
final ArrayAdapter adpt=新的ArrayAdapter(这是android.R.layout.simple\u list\u item\u 1,myfoodList);
rv.设置适配器(adpt);
ref.orderByKey().limitToLast(1).addChildEventListener(新的ChildEventListener()){
@凌驾
公共void onChildAdded(DataSnapshot DataSnapshot,字符串s){
//ArrayList message=dataSnapshot.getValue(ArrayList.class);
GenericTypeIndicator t=新的GenericTypeIndicator(){};
列表消息=dataSnapshot.getValue(t);
myfoodList.clear();
myfoodList.addAll(消息);
//myfoodList=消息;
adpt.notifyDataSetChanged();
}

我尝试了第二个代码,但得到了以下结果:`java.lang.NullPointerException:尝试在android.widget.ArrayAdapter.createViewFromResource(ArrayAdapter.java:409)的空对象引用上调用虚拟方法'java.lang.String java.lang.Object.toString()`在
ArrayAdapter.java
中似乎存在与此问题无关的空值。但是,您可能在适配器中使用了
toString()
方法,该方法为空值,因此,您可以先进行如下检查:
if(myString!=null){然后获取字符串}
实际上
if(myString!=null)
删除了错误,但我的列表视图中没有任何内容,这意味着mystring实际上是空的。现在我明白了。我很困惑。感谢添加图片,您可以尝试检查
mystring
以查看您是否获得了数据。然后尝试添加到列表中,等等。您尝试添加到列表中的可能是空的。添加到列表后,也可调用
Notifydatachange
。在child之后(“冰箱”)您需要再添加一个子项,即生成用于存储foodPossible duplicate of Btw的按键。在我稍微更改了数据库结构并使其看起来像这样之后,这就起作用了:您更改了数据库结构,这就是它起作用的原因。总之,
child(“冰箱”).child(“食物”)
可以帮助获得我在回答中提到的第一个结构的数据。
for(DataSnapshot ds : dataSnapshot.getChildren()) {

   String myString = ds.child("food").getValue(String.class));

   // print myString or add to list..
}
ref = FirebaseDatabase.getInstance().getReference().child("fridge").child("food")...// listener
food = (TextView) findViewById(R.id.food);
        rv = (ListView) findViewById(R.id.myrv);
        ref = FirebaseDatabase.getInstance().getReference().child("fridge2");
        final ArrayAdapter<String> adpt = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, myfoodList);
        rv.setAdapter(adpt);

        ref.orderByKey().limitToLast(1).addChildEventListener(new ChildEventListener() {
            @Override
            public void onChildAdded(DataSnapshot dataSnapshot, String s) {
               // ArrayList message = dataSnapshot.getValue(ArrayList.class);

                GenericTypeIndicator<List<String>> t = new GenericTypeIndicator<List<String>>() {};
                List<String> message = dataSnapshot.getValue(t);

                myfoodList.clear();
                myfoodList.addAll(message);

                //myfoodList = message;
                adpt.notifyDataSetChanged();
            }