首页 > 解决方案 > 如何将 Firebase 中的所有数据读入列表视图

问题描述

我正在尝试将我所有存储的数据从 firebase 读取到列表视图中。首先,我无法弄清楚如何引用通过 push() 创建的自动生成的密钥;这意味着我无法使用 getter & setter,因为它总是独一无二的。我还可以在如何遍历所有歌曲方面提供一些帮助。任何帮助表示赞赏。

我的 getter 和 setter 类获取所需的字段但无法获取密钥。

Firebase 结构

protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_added_songs);

        firebaseAuth = FirebaseAuth.getInstance();


        listView = (ListView)findViewById(R.id.songsListView);
        databaseReference = FirebaseDatabase.getInstance().getReference();
        databaseReference.child("Songs").child("Added Songs").push().getKey();

        authStateListener = new FirebaseAuth.AuthStateListener() {
            @Override
            public void onAuthStateChanged(@NonNull FirebaseAuth firebaseAuth) {
                FirebaseUser user = firebaseAuth.getCurrentUser();
                if (user != null) {
                    // User is signed in
                    Log.d(TAG, "onAuthStateChanged:signed_in:" + user.getUid());
                } else {
                    // User is signed out
                    Log.d(TAG, "onAuthStateChanged:signed_out");
                }

            }
        };

        databaseReference.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {

                showData(dataSnapshot);
            }

            @Override
            public void onCancelled(@NonNull DatabaseError databaseError) {

            }
        });

    }

   private void showData(DataSnapshot dataSnapshot){
    for (DataSnapshot ds : dataSnapshot.getChildren()){
        System.out.println(ds.getKey());
        Songs songs = new Songs();
        songs.setSongId(ds.getKey()); // --> Set the song ID that is requested
        songs.setArtist_name(ds.getValue(Songs.class).getArtist_name());
        songs.setGenre(ds.getValue(Songs.class).getGenre());
        songs.setLocation(ds.getValue(Songs.class).getLocation());
        songs.setSong_link(ds.getValue(Songs.class).getSong_link());
        songs.setSong_name(ds.getValue(Songs.class).getSong_name());

        ArrayList<String> array = new ArrayList<>();
        array.add(songs.getArtist_name());
        array.add(songs.getGenre());
        array.add(songs.getLocation());
        array.add(songs.getSong_link());
        array.add(songs.getSong_name());
        array.add(songs.getSongId()); // --> Set the ID to the song
        ArrayAdapter adapter = new ArrayAdapter(this,android.R.layout.simple_dropdown_item_1line);
        listView.setAdapter(adapter);
    }
}

标签: androidfirebasefirebase-realtime-database

解决方案


就像弗兰克的回答一样,您的 POJO 中也可以有一个字符串歌曲 ID,当您检索每个键时,getKey()您可以将该键存储到数组中,因此,当您膨胀每一行的视图时,您可以单击它们,它们会将唯一键分配给列表中的每首歌曲。

示例(从弗兰克的回答中,你得到了钥匙)

private void showData(DataSnapshot dataSnapshot){
    for (DataSnapshot ds : dataSnapshot.getChildren()){
        System.out.println(ds.getKey());
        Songs songs = new Songs();
        songs.setSongId(ds.getKey()); // --> Set the song ID that is requested
        ArrayList<String> array = new ArrayList<>();
        array.add(songs.getSongId()); // --> Set the ID to the song

有了这个,您可以为列表中的每首歌曲分配其唯一 ID,因此每当您在列表中单击它们时,您都可以访问它们的特定 ID 以检索您需要的数据。

编辑

我认为该列表没有显示任何内容,因为当您初始化时您ArrayAdapter没有将获取的数据传递给它,请查看构造函数

ArrayAdapter(Context context, int resource, List<T> objects)

看看你的

ArrayAdapter adapter = new ArrayAdapter(this,android.R.layout.simple_dropdown_item_1line);

您缺少适配器的数据,请将其更改为此

ArrayAdapter adapter = new ArrayAdapter(this,android.R.layout.simple_dropdown_item_1line,array);

由于它在 for 循环中,您将看到项目被一一填充;如果您只想同时弹出所有项目,请将这两行移到 for 循环之外

for (DataSnapshot ds : dataSnapshot.getChildren()){
//...
}
ArrayAdapter adapter = new ArrayAdapter(this,android.R.layout.simple_dropdown_item_1line,array);
listView.setAdapter(adapter);

此外,非常重要的一点是不要在每次循环数据时都创建一个新数组,您需要创建将在数组中的新对象,但是每次循环都不需要创建一个新数组来获得目的。

所以将你的 ArrayList 声明移到你的 for 循环之外

ArrayList<String> array = new ArrayList<>();
for (DataSnapshot ds : dataSnapshot.getChildren()){
    //...
    }
    ArrayAdapter adapter = new ArrayAdapter(this,android.R.layout.simple_dropdown_item_1line,array);
    listView.setAdapter(adapter);

此外,数组应该是 Songs 类型,并将适配器更改为自定义适配器,但现在,我认为它应该可以正常工作。


推荐阅读