Firebase RecyclerView 显示一项
Firebase RecyclerView Displays One Item
在我的数据库中,我有包含多首歌曲的条目。这就是数据库的样子,以及显示器中显示的内容:
"DjSunGazer" : {
"song" : {
"-LmHrkYkU1qD2GND9wY2" : "Blaya - Cash",
"-LmHrlalIVUStU6nqBJI" : "Blaya - Cash",
"-LmHrmRRXy4UYoF7DNZz" : "Taylor Swift - You Need to Calm Down"
}
},
在我的应用程序中,我能够使用哈希图为每首独特的歌曲分配一个计数器。现在,在 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)" 并带有 1 标志表示在数据库中仅出现一次的值,而不是仅显示 "Ginuwine - So Anxious"(3) 以及低于该值第一次进入。这已经在我的 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);
问题出在您的 json 结构上。在这种情况下,您可能希望为歌曲使用 json 数组,并且可能有一个 Song
对象。现在,他们很可能被解析为一个单独的 "song",这实际上是一个 String
。类似于以下 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 结构,这样更容易解析。现在,您似乎将艺术家的名字作为歌曲集的键值,我认为这也会导致问题或使事情变得比他们需要的更困难。
根据您的需要填写有效的 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"}]}}
修复了我的解决方案以使用自定义 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 class:
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!
在我的数据库中,我有包含多首歌曲的条目。这就是数据库的样子,以及显示器中显示的内容:
"DjSunGazer" : {
"song" : {
"-LmHrkYkU1qD2GND9wY2" : "Blaya - Cash",
"-LmHrlalIVUStU6nqBJI" : "Blaya - Cash",
"-LmHrmRRXy4UYoF7DNZz" : "Taylor Swift - You Need to Calm Down"
}
},
在我的应用程序中,我能够使用哈希图为每首独特的歌曲分配一个计数器。现在,在 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)" 并带有 1 标志表示在数据库中仅出现一次的值,而不是仅显示 "Ginuwine - So Anxious"(3) 以及低于该值第一次进入。这已经在我的 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);
问题出在您的 json 结构上。在这种情况下,您可能希望为歌曲使用 json 数组,并且可能有一个 Song
对象。现在,他们很可能被解析为一个单独的 "song",这实际上是一个 String
。类似于以下 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 结构,这样更容易解析。现在,您似乎将艺术家的名字作为歌曲集的键值,我认为这也会导致问题或使事情变得比他们需要的更困难。
根据您的需要填写有效的 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"}]}}
修复了我的解决方案以使用自定义 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 class:
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!