【问题标题】:Showing Firebase data in ListView在 ListView 中显示 Firebase 数据
【发布时间】:2021-12-23 09:36:10
【问题描述】:

好的,我让它运行显示用户 ID 但不显示分数。然后我开始做一些改变,忘记了我改变了什么,现在我又回到了 null null 。我觉得我可能删除了某些内容或拼错了某些内容。

   dbref.addValueEventListener(new com.google.firebase.database.ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {

                ArrayList<String> list = new ArrayList<>();
                list.clear();

                for(DataSnapshot ds :dataSnapshot.getChildren()) {
                    Score Result = ds.getValue(Score.class);
                    String userId = String.valueOf(Result.getUserId());
                    String score = String.valueOf(Result.getScore());
                    list.add(userId);
                    list.add(score);

                }
                adapter = new ArrayAdapter<>(getActivity(), android.R.layout.simple_list_item_1, list);
                LvRanking.setAdapter(adapter);
            }

这是我的模型:

public class Score {
private String userId, score;

public Score() {}

public Score(String userId, String score) {
    this.userId = userId;
    this.score = score;
}

public String getUserId() {
    return userId;
}

public String getScore() {
    return score;
}

@Override
public String toString() {
    return "Score{" +
            "userId='" + userId + '\'' +
            ", score='" + score + '\'' +
            '}';
}
 }

数据库: Link to my database screenshot

【问题讨论】:

  • 你能把你的“logcat print for when crash发生吗?通常是红色文本。LogCat在Android Studio的底部或View > Tool Windows > LogCat
  • logcat 崩溃时没有写入任何内容,我通过底部导航栏导航到片段。当我单击按钮时,应用程序会停止,并且 logcat 没有说明原因。
  • 这是一种奇怪的行为。您正在使用模拟器或移动连接与 Android Studio 对吗?如果是,也许您需要更改 logcat 中的过滤器。在您看到“仅显示选定的应用程序”的地方放置“无过滤器”并在第三个下拉菜单上选择详细。
  • 你的 logcat 中的错误是什么?
  • 参见上面的编辑,应用程序不再崩溃,只是说 null:null 。

标签: java android listview firebase firebase-realtime-database


【解决方案1】:

这是异步 API 的一个经典问题。为了使其工作,请根据Java Naming Conventions 更改您的模型类。你的类应该是这样的:

public class Score {
    private String userId, score;

    public Score() {}

    public Score(String userId, String score) {
        this.userId = userId;
        this.score = score;
    }

    public String getUserId() {
        return userId;
    }

    public String getScore() {
        return score;
    }

    @Override
    public String toString() {
        return "Score{" +
                "userId='" + userId + '\'' +
                ", score='" + score + '\'' +
                '}';
    }
}

还要注意onDataChange() 方法具有异步行为,这意味着即使在您尝试将Score 类的那些对象添加到列表之前,它也会被调用。换句话说,您的 list 在该方法之外将始终为空。一个快速的解决方法是将列表的声明移到 onDataChange() 中并做你想做的事情,或者,如果你想深入异步世界并使用我在 post 中的回答。

假设 score 节点是 Firebase 根的直接子节点,要使用 String 类显示数据,请使用以下代码:

ListView listView = (ListView) findViewById(R.id.list_view);
List<String> list = new ArrayList<>();
ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_1, list);
listView.setAdapter(arrayAdapter);
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference scoreRef = rootRef.child("score");
ValueEventListener eventListener = new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
        for(DataSnapshot ds : dataSnapshot.getChildren()) {
            String userId = ds.child("userId").getValue(String.class);
            String score = ds.child("score").getValue(String.class);
            list.add(userId + " / " +  score);
            Log.d("TAG", userId + " / " +  score);
        }
        arrayAdapter.notifyDataSetChanged();
    }

    @Override
    public void onCancelled(DatabaseError databaseError) {
        Log.d(TAG, task.getException().getMessage());
    }
};
scoreRef.addListenerForSingleValueEvent(eventListener);

这就是使用Score 类显示数据的方式。

ValueEventListener eventListener = new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
        for(DataSnapshot ds : dataSnapshot.getChildren()) {
            Score score = ds.getValue(Score.class);
            String userId = score.getUserId();
            String score = score.getScore();
            Log.d("TAG", userId + " / " +  score);
            list.add(score);
        }
        arrayAdapter.notifyDataSetChanged();
    }

    @Override
    public void onCancelled(DatabaseError databaseError) {
        Log.d(TAG, task.getException().getMessage());
    }
};
scoreRef.addListenerForSingleValueEvent(eventListener);

【讨论】:

  • 您是否在onDataChange() 方法中创建列表并将适配器设置在同一个位置?
  • @AlexMamo 是的,除了 Listview LvRanking 之外,所有内容都在该方法中;和 LvRanking = ...(R.id.LvRanking);
  • @AlexMamo 现在编辑并添加了数据库截图。非常感谢您的帮助
  • 不正确。您没有更改模型类,正确命名字段很重要。请参阅here 在哪里设置适配器。
  • @AlexMamo 我不太清楚你的意思.. 我只使用 Android 大约一个月。我将尝试实现您发送的链接。谢谢
【解决方案2】:

filepath.addOnSuccessListener(先上传数据)然后获取并使用....

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-05-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-04
    相关资源
    最近更新 更多