Firebase RecyclerView 只显示一个项目

6
在我的数据库中,有多个歌曲的条目。这是数据库的样子,也是显示的内容:
  "DjSunGazer" : {
    "song" : {
      "-LmHrkYkU1qD2GND9wY2" : "Blaya - Cash",
      "-LmHrlalIVUStU6nqBJI" : "Blaya - Cash",
      "-LmHrmRRXy4UYoF7DNZz" : "Taylor Swift - You Need to Calm Down"
    }
  },

enter image description here

在我的应用程序中,我能够使用哈希映射将每个唯一的歌曲与计数器相对应。现在,在Firebase RecyclerView Adapter中,它只显示数据库中的最后一个条目。以下是代码:

            query = mProfileDatabase.child(djName);

            FirebaseRecyclerOptions<DataSnapshot> firebaseRecyclerOptions =
                    new FirebaseRecyclerOptions.Builder<DataSnapshot>()
                    .setQuery(query, new SnapshotParser<DataSnapshot>(){
                        @NonNull
                        @Override
                        public DataSnapshot parseSnapshot(@NonNull DataSnapshot snapshot)
                        {
                            return snapshot;
                        }
                    }).build();

            final HashMap<String, Integer> songCounts = new HashMap<String, Integer>();

            firebaseRecyclerAdapter =
                    new FirebaseRecyclerAdapter<DataSnapshot, ResultsViewHolder>(firebaseRecyclerOptions)
                    {

                        @Override
                        protected void onBindViewHolder(@NonNull ResultsViewHolder holder, int position, @NonNull DataSnapshot model)
                        {
                            List<String> sArr = new ArrayList<String>();
                            for(DataSnapshot snapshot : model.getChildren())
                            {
                                sArr.add(snapshot.getValue(String.class));
                            }


                            for(int i = 0; i < sArr.size(); i++)
                            {
                                String eachSong = sArr.get(i);
                                if(songCounts.containsKey(eachSong))
                                {
                                    int count = songCounts.get(eachSong);
                                    songCounts.put(eachSong, count + 1);
                                }
                                else
                                {
                                    songCounts.put(eachSong, 1);
                                }
                            }

                            Collection<String> name = songCounts.keySet();
                            Collection<Integer> ctn = songCounts.values();

                            for(String s2 : name)
                            {
                                Log.d("INFO", s2);
                                DisplaySong ds = new DisplaySong(s2);
                                ds.setSong(s2);
                                holder.setDJNameView(ds);
                            }
                            for(Integer i : ctn)
                            {
                                holder.setBadgeCount(i);
                            }
                        }


                        @NonNull
                        @Override
                        public ResultsViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i)
                        {
                            View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.djname_item, viewGroup, false);
                            return new ResultsViewHolder(view);
                        }
                    };
            firebaseRecyclerAdapter.startListening();
            recyclerView.setAdapter(firebaseRecyclerAdapter);
            songCounts.clear();

我希望在RecyclerView中不仅显示值为"Rick Ross - Gold Roses (feat.Drake)",还要显示下面的第一条目录下有3个出现次数的"Ginuwine - So Anxious"。这已经在我的songCounts HashMap中计算和处理过了。谢谢!

编辑添加了dj_name_item.xml

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:padding="8dp">

        <TextView
            android:id="@+id/song_result_dj"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_centerVertical="true"
            android:layout_marginLeft="30dp"
            android:layout_marginRight="30dp" />
        <TextView
            android:id="@+id/song_badge"
            android:layout_width="20dp"
            android:layout_height="20dp"
            android:layout_gravity="right|end|top"
            android:layout_marginTop="3dp"
            android:layout_marginEnd="-5dp"
            android:layout_marginRight="15dp"
            android:background="@drawable/badge_background"
            android:gravity="center"
            android:padding="3dp"
            android:paddingRight="15dp"
            android:text="0"
            android:textColor="@android:color/white"
            android:textSize="10sp" />
    </RelativeLayout>

编辑:添加了数据插入方式

FirebaseDatabase.getInstance().getReference().child(djName).child("song").push().setValue(songName);


加入 R.layout.djname_item 怎么样(我会怀疑这个)? - Martin Zeitler
好的,已添加 :) - beastlyCoder
@MartinZeitler 你说得对。RelativeLayouts 没有方向属性。 - Taslim Oseni
我已经找到了解决方案,稍晚一些时候我会详细讲述我是如何解决的。 :) - beastlyCoder
最终将从问题中删除。 - beastlyCoder
显示剩余4条评论
3个回答

3
问题在于你的json结构。在这种情况下,你应该使用一个json数组来存储歌曲,并且很可能需要有一个“Song”对象。目前,它们很可能被解析为仅仅是一个单独的“歌曲”,实际上是一个字符串。以下json结构将是正常工作的开始:
  "DjSunGazer" : {
    "songs" : [
      { "id" : "-LmHrkYkU1qD2GND9wY2", "name" : "Ginuwine - So Anxious" },
      { "id" : "-LmHrlalIVUStU6nqBJI", "name" : "Ginuwine - So Anxious" },
      { "id" : "-LmHrmRRXy4UYoF7DNZz", "name" : "Ginuwine - So Anxious" },
      { "id" : "-LmHrpZzOKOtY_8AGQ_S", "name" : "Rick Ross - Gold Roses (feat. Drake) }"
    ]
  }

我仍然建议进一步更新json结构,以便更容易解析。目前,似乎你正在将艺术家的名字作为歌曲集的键值包含在内,这可能会导致问题或使事情比必要的更加困难。


如果我展示用于插入数据库的原始代码,你能否展示一个如何实现这个结构的例子? - beastlyCoder
这似乎很可能是因为那些节点应该有 {} 而不是 ""... 添加类似于 PlaylistSong 的模型类也会减少阅读时的工作量。 - Martin Zeitler
@beastlyCoder 当然可以。我觉得它应该已经基本完成了,但是我可以在今天/明天稍后更新有关Firebase方面的更多细节... - Submersed
谢谢,我会发布我如何添加信息的内容。 - beastlyCoder

1
根据您的需求,完整且有效的JSON文件。
{"DjSunGazer": {
"songs": [{
"-LmHrkYkU1qD2GND9wY2 ": "Blaya - Cash ",
"-LmHrlalIVUStU6nqBJI": "Blaya - Cash",
"-LmHrmRRXy4UYoF7DNZz": "Taylor Swift - You Need to Calm Down"},{
"-LmHrkYkU1qD2GND9wY2 ": "Blaya - Cash ",
"-LmHrlalIVUStU6nqBJI": "Blaya - Cash",
"-LmHrmRRXy4UYoF7DNZz": "Taylor Swift - You Need to Calm Down"},{
"-LmHrkYkU1qD2GND9wY2 ": "Blaya - Cash ",
"-LmHrlalIVUStU6nqBJI": "Blaya - Cash",
"-LmHrmRRXy4UYoF7DNZz": "Taylor Swift - You Need to Calm Down"},{
"-LmHrkYkU1qD2GND9wY2 ": "Blaya - Cash ",
"-LmHrlalIVUStU6nqBJI": "Blaya - Cash",
"-LmHrmRRXy4UYoF7DNZz": "Taylor Swift - You Need to Calm Down"}]}}

1

我修复了我的解决方案,使用了自定义的Firebase适配器。这有助于解决手动添加每个子视图的问题。

    songNames = new ArrayList<String>();

    mProfileDatabase.addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot dataSnapshot)Aft
        {

            mProfileDatabase.child(djName).child("song")
                    .addListenerForSingleValueEvent(new ValueEventListener() {
                        @Override
                        public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                            List<String> sArr = new ArrayList<String>();
                            for(DataSnapshot snapshot:dataSnapshot.getChildren()){
                                sArr.add(snapshot.getValue(String.class));
                            }

                            LinkedHashMap<String, Integer> songCounts = new LinkedHashMap<>();
                            for(int i = 0; i < sArr.size(); i++)
                            {
                                String eachSong = sArr.get(i);
                                if(songCounts.containsKey(eachSong))
                                {
                                    int count = songCounts.get(eachSong);
                                    songCounts.put(eachSong, count + 1);
                                }
                                else
                                {
                                    songCounts.put(eachSong, 1);
                                }
                            }
                            ArrayList<POJO> arrayList = new ArrayList<>();
                            for(Map.Entry<String,Integer> s:songCounts.entrySet()){
                                POJO pojo = new POJO(s.getKey(),s.getValue());
                                arrayList.add(pojo);
                            }

                            CustomRecyclerAdapter adapter = new CustomRecyclerAdapter(DjLanding.this,arrayList);
                            recyclerView.setAdapter(adapter);

                        }

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

                        }
                    });
        }


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

        }
    });

这是我的自定义适配器的定义:

public class CustomRecyclerAdapter extends RecyclerView.Adapter<CustomRecyclerAdapter.ViewHolder>
{

    private Context context;
    private ArrayList<POJO> personUtils;

    public CustomRecyclerAdapter(Context context, ArrayList<POJO> personUtils) {
        this.context = context;
        this.personUtils = personUtils;
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.djname_item, parent, false);
        ViewHolder viewHolder = new ViewHolder(v);
        return viewHolder;
    }

    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        holder.itemView.setTag(personUtils.get(position));
        POJO pu = personUtils.get(position);
        holder.djNameView.setText(pu.getName());
        holder.badge.setText(pu.getCount()+"");
    }

    @Override
    public int getItemCount() {
        return personUtils.size();
    }

    public class ViewHolder extends RecyclerView.ViewHolder
    {
        public TextView djNameView;
        public TextView badge;
        public ViewHolder(View itemView) {
            super(itemView);
            djNameView = itemView.findViewById(R.id.song_result_dj);
            badge = itemView.findViewById(R.id.song_badge);
        }
    }
}

这是我的普通Java类:

public class POJO
{
    String name;
    Integer count;

    public POJO(String name, Integer count) {
        this.name = name;
        this.count = count;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getCount() {
        return count;
    }

    public void setCount(Integer count) {
        this.count = count;
    }
}

感谢Hariom!

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接