我想从firebase实时数据库中显示recyclerview android上的数据..但我无法将动态数据加载到适配器数组中
Posted
技术标签:
【中文标题】我想从firebase实时数据库中显示recyclerview android上的数据..但我无法将动态数据加载到适配器数组中【英文标题】:I want to show data on recyclerview android from firebase realtime database.. but i am unable to load dynamic data into adapter array 【发布时间】:2021-10-07 01:07:55 【问题描述】:我想在 android 的 recyclerview 中显示数据。数据将从 Firebase 实时数据库中检索,但我遇到了一个奇怪的问题。
为了从数据库中获取所需的数据,我想在两个不同的节点读取数据库两次。
我在下面附上了我的代码,以及数据结构的可视化概览。
RecyclerView 只显示演示值,它被硬编码到适配器数组中。它没有显示应该从 for 循环内部添加的数据。
请注意:我的适配器和助手都是正确的。
我在下面附上了我的代码:
`
package com.example.attendx;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import com.bumptech.glide.Glide;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;
import java.util.ArrayList;
public class dashboard extends AppCompatActivity
RecyclerView featuredrecycler;
RecyclerView.Adapter adapter;
ArrayList<FeaturedHelper> admin_cls = new ArrayList<FeaturedHelper>();
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_dashboard);
//Hooks Recycler view
featuredrecycler = findViewById(R.id.featured_recycler);
DatabaseReference Root_Ref, UserProfile_Ref;
Root_Ref = FirebaseDatabase.getInstance().getReference();
UserProfile_Ref = Root_Ref.child("userprofile").child(uid);
DatabaseReference User_Sir_ji_Ref;
User_Sir_ji_Ref = UserProfile_Ref.child("Sir_ji");
//method created for recycler view
featuredrecycler(User_Sir_ji_Ref, Root_Ref);
private void featuredrecycler(DatabaseReference user_Sir_ji_Ref, DatabaseReference root_Ref)
featuredrecycler.setHasFixedSize(true);
featuredrecycler.setLayoutManager(new LinearLayoutManager(dashboard.this, LinearLayoutManager.HORIZONTAL, false));
//ArrayList<FeaturedHelper> admin_cls = new ArrayList<>();
admin_cls.add(new FeaturedHelper(R.drawable.icon, "test0", "test2")); // This DEMO SHOWS
user_Sir_ji_Ref = user_Sir_ji_Ref;
user_Sir_ji_Ref.addListenerForSingleValueEvent(new ValueEventListener()
@Override
public void onDataChange(@NonNull DataSnapshot snapshot)
if(snapshot.exists())
DatabaseReference ClassHeader;
ClassHeader = root_Ref.child("clas-s-room_header");
for(DataSnapshot snapshot1 : snapshot.getChildren())
Log.d("SNAPSHOT", snapshot1.getValue().toString());
ClassHeader.child(snapshot1.getValue().toString()).addListenerForSingleValueEvent(new ValueEventListener()
@Override
public void onDataChange(@NonNull DataSnapshot snapshot)
String Cls_name, createdBy;
Cls_name = snapshot.child("ClassName").getValue().toString();
createdBy = snapshot.child("TeacherName").getValue().toString();
admin_cls.add(new FeaturedHelper(R.drawable.icon, Cls_name, createdBy)); // THIS DOESNOT SHOWS
Log.d("SNAPSHOT", Cls_name+"\n"+createdBy);
@Override
public void onCancelled(@NonNull DatabaseError error)
Toast.makeText(getApplicationContext(), "Recycler View Error.", Toast.LENGTH_SHORT).show();
);
@Override
public void onCancelled(@NonNull DatabaseError error)
Toast.makeText(getApplicationContext(), "UNABLE_TO_READ_SIR_JI", Toast.LENGTH_SHORT).show();
);
Log.d("SNAPSHOT", admin_cls.toString()); // HERE IT SHOWS ONLY ONE ELEMENT
adapter = new FeaturedAdapter(admin_cls);
featuredrecycler.setAdapter(adapter);
`
请帮我解决这个奇怪的问题。
数据库结构见以下链接:
userprofile node has sir_ji node inside, which has class_id
class_header node has node of class_id, which contains class details
【问题讨论】:
你能分享你的json数据库吗? 是的,请稍等片刻......但我想提一下,使用日志我已经验证我在 Cls_name 和 for 循环中的 createdBy 变量中获得了所需的值 那么你想得到的确切数据是什么,按什么顺序?请回复@AlexMamo 【参考方案1】:Firebase 以异步方式工作,您应该将代码放在方法onDataChange
中。由于您使用的是 for loop
并在其中连接 Firebase,因此您可以在检索值时为其创建延迟。
for(DataSnapshot snapshot1 : snapshot.getChildren())
Log.d("SNAPSHOT", snapshot1.getValue().toString());
//Here your all codes...
//Here you call the this function.
//1000 = 1 second
CreateDelay(1000, () ->
Log.d("SNAPSHOT", admin_cls.toString());
adapter = new FeaturedAdapter(admin_cls);
featuredrecycler.setAdapter(adapter);
);
方法CreateDelay
及其接口
public static void CreateDelay(final long delayMillis, @NonNull final DelayCallback delayCallback)
final Looper l = Looper.myLooper();
if (l != null)
new Handler(l).postDelayed(delayCallback::onFinished, delayMillis);
@FunctionalInterface
public interface DelayCallback
void onFinished();
【讨论】:
谢谢,但所有代码都意味着在其中创建数组或像之前一样向数组添加值?? 对不起,我不明白你的问题@MillenniumChowdhury 如果您看到我之前的代码,我已经在 ondatachange 内的数组中添加了值...但是在 ondata change 适配器之外设置了适配器 = new FeaturedAdapter(admin_cls); featuresrecycler.setAdapter(适配器);现在我应该在 ondatachanged 中定义数组并设置适配器 @MillenniumChowdhury 是的,你可以试试我的答案,在onDataChange
中定义它【参考方案2】:
当您更改 admin_cls
中的数据时,您需要告诉适配器该事实,以便它知道重新呈现视图。
每当您对admin_cls
中的数据进行更改(或完成更改)时,您都可以通过调用adapter.notifyDataSetChanged()
来执行此操作。
user_Sir_ji_Ref.addListenerForSingleValueEvent(new ValueEventListener()
@Override
public void onDataChange(@NonNull DataSnapshot snapshot)
if(snapshot.exists())
DatabaseReference ClassHeader;
ClassHeader = root_Ref.child("clas-s-room_header");
for(DataSnapshot snapshot1 : snapshot.getChildren())
ClassHeader.child(snapshot1.getValue().toString()).addListenerForSingleValueEvent(new ValueEventListener()
@Override
public void onDataChange(@NonNull DataSnapshot snapshot)
String Cls_name, createdBy;
Cls_name = snapshot.child("ClassName").getValue().toString();
createdBy = snapshot.child("TeacherName").getValue().toString();
admin_cls.add(new FeaturedHelper(R.drawable.icon, Cls_name, createdBy));
adapter.notifyDataSetChanged(); // ? Add this
【讨论】:
以上是关于我想从firebase实时数据库中显示recyclerview android上的数据..但我无法将动态数据加载到适配器数组中的主要内容,如果未能解决你的问题,请参考以下文章
如何将Firebase Recycler视图从最新(列表顶部)排序到最旧[重复]
读取 longlat 数据实时 Firebase 和实现以映射 Android Studio