I am using a RecyclerView in which I get data from a Firestore database. Here's my code for the adapter. Please pay attention to the two Log.d()
statements in the constructor and one in getItemCount()
.
public class DonorDonateAdapter extends RecyclerView.Adapter<DonorDonateAdapter.DonorDonateViewHolder> {
public String email;
public static CircularImageView imageView;
public List<String> planters;
private FirebaseFirestore database;
public static class DonorDonateViewHolder extends RecyclerView.ViewHolder {
public Button profileButton;
public TextView nameTextView;
public TextView addressTextView;
public ImageView donateIcon;
public ImageView messageIcon;
DonorDonateViewHolder(View view) {
super(view);
profileButton = view.findViewById(R.id.profile_button);
imageView = view.findViewById(R.id.image_view);
nameTextView = view.findViewById(R.id.text_view_name);
addressTextView = view.findViewById(R.id.text_view_address);
donateIcon = view.findViewById(R.id.donate_icon);
messageIcon = view.findViewById(R.id.message_icon);
MainActivity.setTextSize(nameTextView);
MainActivity.setTextSize(addressTextView);
}
}
DonorDonateAdapter(String email) {
this.email = email;
this.database = FirebaseFirestore.getInstance();
this.planters = new ArrayList<>();
this.database.collection("Planters").orderBy("Trees Planted", Query.Direction.DESCENDING).get()
.addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() {
@Override
public void onSuccess(QuerySnapshot queryDocumentSnapshots) {
for (QueryDocumentSnapshot documentSnapshot : queryDocumentSnapshots) {
planters.add(documentSnapshot.getId());
Log.d("cs50", "onSuccess() planters.size() = " + planters.size());
}
}
}).addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
Log.e("cs50", "Error getting planters", e);
}
});
Log.d("cs50", "constructor planters.size() = " + planters.size());
}
// List<String> planters = MainActivity.appDatabase.plantersDao().getAllPlantersByTreesPlanted();
@NonNull
@Override
public DonorDonateViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.donor_planter, parent, false);
Log.d("cs50", "onCreate() runs");
return new DonorDonateViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull final DonorDonateViewHolder holder, int position) {
final String current = planters.get(position);
Log.d("cs50", "onBind() runs");
database.collection("Planters").document(current).get()
.addOnSuccessListener(new OnSuccessListener<DocumentSnapshot>() {
@Override
public void onSuccess(DocumentSnapshot documentSnapshot) {
if (documentSnapshot.getString("ImageURL") != null) {
new DownloadImageTask(imageView).execute(documentSnapshot.getString("ImageURL"));
}
String name = documentSnapshot.getString("Name");
if (name.length() <= 16) {
holder.nameTextView.setText(name);
} else {
holder.nameTextView.setText(name.substring(0, 12) + "...");
}
String address = documentSnapshot.getString("City") + ", " + documentSnapshot.getString("Country");
if (address.length() <= 16) {
holder.addressTextView.setText(address);
} else {
holder.addressTextView.setText(address.substring(0, 12) + "...");
}
}
}).addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
Log.e("cs50", "Error checking if planter exists", e);
}
});
holder.profileButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent profileIntent = new Intent(view.getContext(), PlanterProfileForDonorActivity.class);
profileIntent.putExtra("email", email);
profileIntent.putExtra("planterEmail", current);
view.getContext().startActivity(profileIntent);
}
});
holder.donateIcon.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent donateIntent = new Intent(view.getContext(), DonateActivity.class);
donateIntent.putExtra("email", email);
donateIntent.putExtra("planterEmail", current);
donateIntent.putExtra("activity", "DonorDonateActivity");
view.getContext().startActivity(donateIntent);
}
});
holder.messageIcon.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent messageIntent = new Intent(view.getContext(), MessageActivity.class);
messageIntent.putExtra("email", email);
messageIntent.putExtra("peerEmail", current);
messageIntent.putExtra("isArchived", false);
view.getContext().startActivity(messageIntent);
}
});
}
@Override
public int getItemCount() {
Log.d("cs50", "getItemCount() planters.size() = " + planters.size());
return planters.size();
}
}
Here's the logcat output I get:
2020-09-21 00:12:31.216 21938-21938/com.example.treeapp D/cs50: constructor planters.size() = 0
2020-09-21 00:12:31.447 21938-21938/com.example.treeapp D/cs50: getItemCount() planters.size() = 0
2020-09-21 00:12:31.462 21938-21938/com.example.treeapp D/cs50: getItemCount() planters.size() = 0
2020-09-21 00:12:31.648 21938-21938/com.example.treeapp D/cs50: getItemCount() planters.size() = 0
2020-09-21 00:12:31.648 21938-21938/com.example.treeapp D/cs50: getItemCount() planters.size() = 0
2020-09-21 00:12:31.682 21938-21938/com.example.treeapp D/cs50: getItemCount() planters.size() = 0
2020-09-21 00:12:31.683 21938-21938/com.example.treeapp D/cs50: getItemCount() planters.size() = 0
2020-09-21 00:12:32.067 21938-21938/com.example.treeapp D/cs50: onSuccess() planters.size() = 1
2020-09-21 00:12:32.068 21938-21938/com.example.treeapp D/cs50: onSuccess() planters.size() = 2
2020-09-21 00:12:32.068 21938-21938/com.example.treeapp D/cs50: onSuccess() planters.size() = 3
2020-09-21 00:12:32.068 21938-21938/com.example.treeapp D/cs50: onSuccess() planters.size() = 4
2020-09-21 00:12:32.068 21938-21938/com.example.treeapp D/cs50: onSuccess() planters.size() = 5
2020-09-21 00:12:32.068 21938-21938/com.example.treeapp D/cs50: onSuccess() planters.size() = 6
2020-09-21 00:12:32.068 21938-21938/com.example.treeapp D/cs50: onSuccess() planters.size() = 7
2020-09-21 00:12:32.068 21938-21938/com.example.treeapp D/cs50: onSuccess() planters.size() = 8
2020-09-21 00:12:32.069 21938-21938/com.example.treeapp D/cs50: onSuccess() planters.size() = 9
2020-09-21 00:12:32.069 21938-21938/com.example.treeapp D/cs50: onSuccess() planters.size() = 10
As you can see, the the constructor finishes executing, and then getItemCount(), and finally my planters list is filled with data from Firestore. As a result, my RecyclerView remains empty. Is there a way to get the Firestore query to execute and the list to fill up before getItemCount() is called?
All I can think of is to make the list in the activity which calls the adapter and pass in the list as a parameter to the constructor for the adapter (and do a similar thing for onResume()
). Is there a better way to do this? I think this is not the way things should be done. If there is no problem with doing this, please let me know.