0

I am using recyclerView and Adapter to fetch the data in profileActivity

here is my

public class studentDetailsRecyclerActivity extends AppCompatActivity {
  //recyclerview  to set the details for UI in the student profile activity

    private RecyclerView mRecyclerView;
    private storeDetailsAdapter mStoreDetailsAdapter;

    private List<storeStudentDetails> studentDetailsList;

    private FirebaseFirestore dbReference;

    private ProgressBar mProgressBar;

    private String TAG = studentDetailsRecyclerActivity.class.getSimpleName();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        dbReference = FirebaseFirestore.getInstance();
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_recycler_details);

        mProgressBar = findViewById(R.id.progressbar);

        mRecyclerView = (RecyclerView)findViewById(R.id.recyclerView_products);
        mRecyclerView.setHasFixedSize(true);
        mRecyclerView.setLayoutManager(new LinearLayoutManager(this));

        studentDetailsList = new ArrayList<>();

        mStoreDetailsAdapter = new storeDetailsAdapter(this,studentDetailsList);

        mRecyclerView.setAdapter(mStoreDetailsAdapter);
        //to get the "details" this is our collection from firestore so we must fetch them
        //by calling the addOnSuccessListener
        dbReference.collection("details").get()
                .addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() {
                    @Override
                    public void onSuccess(QuerySnapshot queryDocumentSnapshots) { //we must have to hide the progress bar when the data gets loaded

                        //here queryDocumentsSnapshot will hold all the "details" which is your collection in firestore

                        if(!queryDocumentSnapshots.isEmpty()){

                            //we must have to create empty list so that to store all
                            //details from DocumentsSnapshots
                            List<DocumentSnapshot>  list =  queryDocumentSnapshots.getDocuments();



                            //enhanced for loop because we have to give every index documentSnapShot

                            for(DocumentSnapshot d: list){

                                storeStudentDetails sd = d.toObject(storeStudentDetails.class);
                                studentDetailsList.add(sd);


                                Log.d(TAG, "onSuccess: " + sd.toString());




                            }

                            //to refresh and sync we must have to use notifyDataSetChanged

                            mStoreDetailsAdapter.notifyDataSetChanged();
                        }
                    }
                })  .addOnFailureListener(new OnFailureListener() {
            @Override
            public void onFailure(@NonNull Exception e) {
                Toast.makeText(getApplicationContext(), "Error getting data!!!", Toast.LENGTH_LONG).show();
            }
        });
    }
}

and here is my storeDetailsAdapter

import java.util.List;

public class storeDetailsAdapter extends RecyclerView.Adapter<storeDetailsAdapter.StudentViewHolder>{

    private Context context;
    private List<storeStudentDetails> studentDetailsList;

    public storeDetailsAdapter(Context context, List<storeStudentDetails> studentDetailsList) {
            this.context = context;
            this.studentDetailsList = studentDetailsList;
    }

    @NonNull
    @Override
    public StudentViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        return new StudentViewHolder(
                LayoutInflater.from(context).inflate(R.layout.profile_activity, parent, false)
        );
    }



    @Override
    public void onBindViewHolder(@NonNull StudentViewHolder holder, int position) {
        storeStudentDetails mStoreDetails = studentDetailsList.get(position);

        holder.studName.setText(mStoreDetails.getStudentName());
        holder.rollNum.setText(mStoreDetails.getRollNo());
        holder.bookName.setText( mStoreDetails.getBook());
        holder.fine.setText("Fine:" + mStoreDetails.getFine());
        holder.dept.setText(mStoreDetails.getDept());

    }

    @Override
    public int getItemCount() {
        return studentDetailsList.size();
    }

    class StudentViewHolder extends RecyclerView.ViewHolder {

        TextView studName,rollNum,bookName,dept,fine;

        public StudentViewHolder(View itemView) {
            super(itemView);

            studName=itemView.findViewById(R.id.studentName_prof);
            rollNum = itemView.findViewById(R.id.rollNumber_prof);
            bookName = itemView.findViewById(R.id.bookName_prof);
            fine = itemView.findViewById(R.id.fineAmt_prof);
            dept = itemView.findViewById(R.id.department_prof);
        }
    }
}

and here is my StoreStudentDetails class:

public class storeStudentDetails implements Serializable {


    private String studentName;
    private  String rollNo;
    private  String book;
    private Double fine;
    private String dept;

    @Exclude private String id;

    public storeStudentDetails() {
    }

    public storeStudentDetails(String studentName, String rollNo,String book, double fine ,String dept) {

        this.studentName = studentName;
        this.rollNo = rollNo;
        this.book = book;
        this.fine = fine;
        this.dept = dept;


    }

    public void setId(String id) {
        this.id = id;
    }

    public String getStudentName() {
        return studentName;
    }

    public String getRollNo() {
        return rollNo;
    }

    public String getBook() {
        return book;
    }

    public Double getFine() {
        return fine;
    }

    public String getDept() {
        return dept;
    }

    public String getId() {
        return id;
    }
}
Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
Thiyagu
  • 49
  • 2
  • 6

1 Answers1

0

To solve this, please move the following lines of code:

mStoreDetailsAdapter = new storeDetailsAdapter(this,studentDetailsList);
mRecyclerView.setAdapter(mStoreDetailsAdapter);

Right before the following line of code:

mStoreDetailsAdapter.notifyDataSetChanged();

And this is because onSuccess() method has an asynchronous behavior and by the time you are setting the adapter outside the callback your list is empty.

As you can see, the easiest solution for this problem is to move those lines of code inside the callback. but if you want to use the value of your studentDetailsList outside the onSuccess() method, I recommend you see the last part of my anwser from this post in which I have explained how it can be done using a custom callback. You can also take a look at this video for a better understanding.

Alex Mamo
  • 130,605
  • 17
  • 163
  • 193