问题
I have tried everything but my data from firebase is not getting loaded automatically when I open the app and I have to click a edittext to load the data.
I have tried
adapter.Update(data);
recycler.invalidate();
notifyDataSetChanged();
adapter.notifyDataSetChanged();
Please can someone help me out.
EDITED:
I am saving to firebase like this:
public FirebaseHelper(DatabaseReference db) {
this.db = db;
}
//WRITE IF NOT NULL
public Boolean save(Spacecraft spacecraft)
{
if(spacecraft==null)
{
saved=false;
}else
{
try
{
db.child("Spacecraft").push().setValue(spacecraft);
saved=true;
}catch (DatabaseException e)
{
e.printStackTrace();
saved=false;
}
}
return saved;
}
//IMPLEMENT FETCH DATA AND FILL ARRAYLIST
private void fetchData(DataSnapshot dataSnapshot)
{
spacecrafts.clear();
for (DataSnapshot ds : dataSnapshot.getChildren())
{
Spacecraft spacecraft=ds.getValue(Spacecraft.class);
spacecrafts.add(spacecraft);
}
}
//READ THEN RETURN ARRAYLIST
public ArrayList<Spacecraft> retrieve() {
db.addChildEventListener(new ChildEventListener() {
@Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
fetchData(dataSnapshot);
}
@Override
public void onChildChanged(DataSnapshot dataSnapshot, String s){
fetchData(dataSnapshot);
}
});
return spacecrafts;
}
}
My viewholder class
public MyViewHolder(View itemView) {
super(itemView);
nameTxt= (TextView) itemView.findViewById(R.id.nameTxt);
propTxt= (TextView) itemView.findViewById(R.id.propellantTxt);
descTxt= (TextView) itemView.findViewById(R.id.descTxt);
itemView.setOnClickListener(this);
}
public void setItemClickListener(ItemClickListener itemClickListener)
{
this.itemClickListener=itemClickListener;
}
@Override
public void onClick(View view) {
this.itemClickListener.onItemClick(this.getLayoutPosition());
}
My adapter class
public class MyAdapter extends RecyclerView.Adapter<MyViewHolder> {
Context c;
ArrayList<Spacecraft> spacecrafts;
public MyAdapter(Context c, ArrayList<Spacecraft> spacecrafts) {
this.c = c;
this.spacecrafts = spacecrafts;
}
@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v=LayoutInflater.from(c).inflate(R.layout.model,parent,false);
return new MyViewHolder(v);
}
@Override
public void onBindViewHolder(MyViewHolder holder, int position) {
final Spacecraft s=spacecrafts.get(position);
holder.nameTxt.setText(s.getName());
holder.propTxt.setText(s.getPropellant());
holder.descTxt.setText(s.getDescription());
holder.setItemClickListener(new ItemClickListener() {
@Override
public void onItemClick(int pos) {
//OPEN DETAI ACTIVITY
openDetailActivity(s.getName(),s.getDescription(),s.getPropellant());
}
});
}
@Override
public int getItemCount() {
return spacecrafts.size();
}
//OPEN DETAIL ACTIVITY
private void openDetailActivity(String...details)
{
Intent i=new Intent(c,DetailActivity.class);
i.putExtra("NAME_KEY",details[0]);
i.putExtra("DESC_KEY",details[1]);
i.putExtra("PROP_KEY",details[2]);
c.startActivity(i);
}
in my mainactivity in onCreate I am calling the data like this
recycler = (RecyclerView) rootView.findViewById(R.id.recycler);
recycler.setLayoutManager(new LinearLayoutManager(getActivity()));
database = FirebaseDatabase.getInstance().getReference();
spacecraft = new ArrayList<>();
firebasehelper = new FirebaseHelper(database);
adapter = new JAdapter(getActivity(), firebasehelper.retrieve());
recycler.setAdapter(adapter);
回答1:
The problem is with the retrieve
method: it's adding a ChildEventListener
that executes asynchronously (meaning it doesn't block until the children data are fetched) and then it immediately returns the spacecrafts
list which is still not yet filled by the asynchronous listener code.
You should refresh the RecyclerView
adapter in the actual code that fetches data, i.e. in the fetchData
method, e.g.:
private void fetchData(DataSnapshot dataSnapshot)
{
spacecrafts.clear();
for (DataSnapshot ds : dataSnapshot.getChildren())
{
Spacecraft spacecraft=ds.getValue(Spacecraft.class);
spacecrafts.add(spacecraft);
}
adapter.spacecrafts = spacecrafts; // update the list in the adapter
adapter.notifyDataSetChanged(); // refresh
}
In this case, the retrieve
method can have a void
return type as it is pointless to return the list from it.
回答2:
Use FirebaseRecyclerAdapter for load the data from Firebase.
回答3:
modify the helper constructer to be like this:
public FirebaseHelper(Context c, DatabaseReference db, ListView lv) {
this.c = c;
this.db = db;
this.lv = lv;
}
then add this to the fetchData method after the for loop:
if (spacecrafts.size() > 0)
{
adapter = new CustomAdapter(c, spacecrafts);
lv.setAdapter(adapter);
adapter.notifyDataSetChanged();
}
then in the main activity modify it like this:
helper = new FirebaseHelper(this, db, lv);
//ADAPTER
//adapter = new CustomAdapter(this, helper.retrieve());
//lv.setAdapter(adapter);
helper.retrieve();
this should work for you.
回答4:
Check if you are setting up adapter in onCreate() method or not, if you are calling it in onStart() then it will not load data automatically. Set Adapter in onCreate() method.
来源:https://stackoverflow.com/questions/41877876/recylerview-not-automatically-loading-data-from-firebase-android-studio