【问题标题】:How to display all childrens from a Firebase node in a RecyclerView in Android?如何在 Android 的 RecyclerView 中显示 Firebase 节点的所有子节点?
【发布时间】:2017-01-17 10:13:26
【问题描述】:

我有一个简单的 Firebase 数据库,如下所示:

我想在RecyclerView 中显示所有这些名称。这是我来自onCreate 方法的代码:

databaseReference = FirebaseDatabase.getInstance().getReference().child("Names");
recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
recyclerView.setHasFixedSize(true);
layoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(layoutManager);
adapter = new RoomFirebaseAdapter(databaseReference, this);
recyclerView.setAdapter(adapter);

我还创建了一个CustomFirebaseAdapter,其中extends RecyclerView.Adapter<CustomFirebaseAdapter.ViewHolder>。这是我的onBindViewHolder 方法:

@Override
public void onBindViewHolder(final RoomFirebaseAdapter.ViewHolder holder, int position) {
    databaseReference.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            for (DataSnapshot ds : dataSnapshot.getChildren()) {
                name = ds.getKey();
                holder.textView.setText(name);
            }
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {}
    });
}

问题是,在我的RecyclerView 中只显示了最后一项。如何显示RecyclerView 中的所有项目?

提前致谢!

【问题讨论】:

    标签: android firebase android-recyclerview firebase-realtime-database


    【解决方案1】:

    您必须从onBindViewHolder 中提取addValueEventListener,并且在此方法中仅设置持有人。最后你也可以使用ChildEventListener 例如:

    private ArrayList<String> names;
    
    public CustomFirebaseAdapter() {
        names = new ArrayList<String>();
        databaseReference = FirebaseDatabase.getInstance().getReference().child("Names");
        updateNames();
    }
    
    private void updateNames() {
        ChildEventListener childEventListener = new ChildEventListener() {
            @Override
            public void onChildAdded(DataSnapshot dataSnapshot, String previousChildName) {
                Log.d(TAG, "onChildAdded:" + dataSnapshot.getKey());
                final String name = dataSnapshot.getValue(String.class);
                names.add(name);
                notifyItemInserted(getItemCount() - 1);
            }
            ...
        };
        databaseReference.addChildEventListener(childEventListener);
    }
    
    @Override
    public void onBindViewHolder(final TodoViewHolder holder, int position) {
        final String name = names.get(position);
        if (name == null) { return; }
    
        holder.textView.setText(name);
    }
    

    我遇到了同样的问题,用这种方法解决了:example

    经过一些调试我们发现,问题是项目布局在更改为wrap_content 后从父级match_parent 占据了整个空间。

    【讨论】:

    • 谢谢,但是当我尝试实现final String name = getItem(position); 时,我得到了这个错误:Cannot resolve method getItem(int)。我能做什么?
    • 它只是返回:names.get(position) 如果names 是你的数组 - 我更新了我的答案
    • 它不工作。现在我得到了一个FATAL EXCEPTION: main java.lang.IndexOutOfBoundsException: Invalid index 0, size is 0。这是我的CustomFirebaseAdapter。而不是名字,我现在有房间。你知道为什么没有给我所有的数据吗?
    • 在我的域上。这是一个简单的java文件。
    • 我的意思是这样我可以下载并测试它
    【解决方案2】:

    我觉得你应该写一个单独的转换器,它实际上是在onDataChange()的方法中转换数据。比你将它传递给你的演示者,它在 RecycleView 上有一个参考

    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
        assets = AssetConverter.convert(dataSnapshot);
        gridPresenter.populate(assets);
    }
    

    gridPresenter 是您在 RecycleView 及其适配器上保存引用的类。

    public void populate(List<Asset> assets) {
        adapter.setData(assets);
        adapter.notifyDataSetChanged();
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-09-22
      • 1970-01-01
      • 1970-01-01
      • 2012-11-25
      • 1970-01-01
      • 2021-05-05
      相关资源
      最近更新 更多