问题
I am trying to add data onto firbase realtime database and retrieve that data on a recyclerview.I am successfully able to do that but when i try to retrieve data from firebase its not happening even-though when i try to print my data on logacat window i am successfully able to do that.
MainActivity.java
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import com.google.firebase.database.ChildEventListener;
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.shivam.fireapp.model.User;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
private Button button;
private Button button2;
EditText editText;
EditText editText2;
String TAG ="MyTag";
private ChildEventListener mchildeventlistener;
private RecyclerView mRecyclerView;
private mModelAdapter modelAdapter;
private List<User> mDataList;
DatabaseReference mRootRef= FirebaseDatabase.getInstance().getReference();
DatabaseReference mRefMain =mRootRef.child("Users");
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button = (Button) findViewById(R.id.Senddata);
button2 = (Button) findViewById((R.id.GetData));
editText = (EditText) findViewById(R.id.Firstname);
editText2 = (EditText) findViewById(R.id.Agee);
mDataList = new ArrayList<>();
mRecyclerView= findViewById(R.id.recyclerView);
mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
modelAdapter = new mModelAdapter(this,mDataList);
mRecyclerView.setAdapter(modelAdapter);
mchildeventlistener = new ChildEventListener() {
@Override
public void onChildAdded(@NonNull DataSnapshot dataSnapshot, @Nullable String s) {
User user = dataSnapshot.getValue(User.class);
mDataList.add(user);
modelAdapter.notifyDataSetChanged();
Log.d(TAG,"OnChildAdded : Name "+ user.getFirst_name());
Log.d(TAG,"OnChildAdded : ageeee "+ user.getAgeeee());
}
@Override
public void onChildChanged(@NonNull DataSnapshot dataSnapshot, @Nullable String s) {
}
@Override
public void onChildRemoved(@NonNull DataSnapshot dataSnapshot) {
}
@Override
public void onChildMoved(@NonNull DataSnapshot dataSnapshot, @Nullable String s) {
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
}
};
mRefMain.addChildEventListener(mchildeventlistener);
}
@Override
protected void onStart(){
super.onStart();
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String Name = editText.getText().toString();
String Age = editText2.getText().toString();
User user = new User(Name,Age);
String key = mRefMain.push().getKey();
mRefMain.child(key).setValue(user);
Toast.makeText(MainActivity.this,"Done",Toast.LENGTH_SHORT).show();
}
});
button2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
}});
}
@Override
protected void onDestroy(){
super.onDestroy();
mRefMain.removeEventListener(mchildeventlistener);
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<Button
android:id="@+id/Senddata"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="32dp"
android:text="Send Data"
app:layout_constraintBottom_toBottomOf="@+id/GetData"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@+id/GetData" />
<EditText
android:id="@+id/Firstname"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="32dp"
android:layout_marginTop="41dp"
android:layout_marginEnd="39dp"
android:ems="10"
android:hint="Enter Name"
android:inputType="textPersonName"
app:layout_constraintEnd_toStartOf="@+id/Agee"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/GetData"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="160dp"
android:layout_marginEnd="40dp"
android:text="Get Data"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<EditText
android:id="@+id/Agee"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="41dp"
android:layout_marginEnd="40dp"
android:ems="10"
android:hint="Entre a Age"
android:inputType="textPersonName"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/Firstname"
app:layout_constraintTop_toTopOf="parent" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="345dp"
android:layout_marginTop="55dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/Senddata" />
</androidx.constraintlayout.widget.ConstraintLayout>
mModelAdapter.java
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.shivam.fireapp.model.User;
import java.util.List;
public class mModelAdapter extends RecyclerView.Adapter<mModelAdapter.MyViewHolder> {
private Context context;
private List<User> mDataList;
public mModelAdapter(Context context, List<User> mDataList) {
this.context = context;
this.mDataList = mDataList;
}
@NonNull
@Override
public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View rootView= LayoutInflater.from(context).inflate(R.layout.recycler_view_item,parent,false);
return new MyViewHolder(rootView);
}
@Override
public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
User user = mDataList.get(position);
holder.textView.setText(user.getFirst_name()+" | "+user.getAgeeee());
}
@Override
public int getItemCount() {
return mDataList.size();
}
public class MyViewHolder extends RecyclerView.ViewHolder{
TextView textView;
public MyViewHolder(@NonNull View itemView) {
super(itemView);
textView = itemView.findViewWithTag(R.id.textView);
}
}
}
User.java
public class User {
String first_name, ageeee;
public User(String first_name, String ageeee) {
this.first_name = first_name;
this.ageeee = ageeee;
}
public User() {
}
public String getFirst_name() {
return first_name;
}
public void setFirst_name(String first_name) {
this.first_name = first_name;
}
public String getAgeeee() {
return ageeee;
}
public void setAgeeee(String ageeee) {
this.ageeee = ageeee;
}
}
recycler_view_item.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/textView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="TextView"
android:textSize="24sp"
android:gravity="center"/>
</LinearLayout>
回答1:
I had the same problem. Its reason is that when firebase hasn't read data from realtime database yet, recyclerview has been made; and it hasn't have any data yet. For solving that you should make recyclerview when you are sure that firebase has read data. Then recyclerview will be made with correct data.
回答2:
First i will recommend you don't pass list in adapter . Create setList
method in adapter.
If you still passing list
in adapter then TRY THIS
Replace this in line childadded
method
modelAdapter.notifyDataSetChanged();
With this two line
modelAdapter = new mModelAdapter(this,mDataList); //this will recreate the adapter with new data
mRecyclerView.setAdapter(modelAdapter); //Again set adapter to recyclerview
回答3:
java inner class dos't access outer local declared variable.So you need do
public List<User> mDataList = new ArrayList<>();
OR
use interface
来源:https://stackoverflow.com/questions/60520000/app-updates-data-in-firebase-real-time-database-but-doesnt-show-anything-in-rec