Search code examples
androidmvvmandroid-recyclerviewviewmodel

RecyclerView not populate on first load


I did some mvvm approach on our application.

Expected Output: RecyclerView will show a list of Contact Addresses on first load.

What happened: RecyclerView is not populate at first load, however if I navigate to other fragment then go back again, the RecyclerView is populate.

I already spend 3 days searching on google for this but none helps.

Fragment:

public class AccountContactAddressFragment extends Fragment {

//Declare Variables
AccountViewModel accountViewModel;
RecyclerView recyclerViewAddresses;
AddressRecyclerViewAdapter addressRecyclerViewAdapter;
ImageButton imageButton;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    // Inflate the layout for this fragment
    return inflater.inflate(R.layout.fragment_account_contact_address, container, false);

}

@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);

    //Initialize ViewModel
    accountViewModel = new ViewModelProvider(getActivity()).get(AccountViewModel.class);

    //Initialize Widgets
    buttonSave = view.findViewById(R.id.buttonSave);
    imageButton = view.findViewById(R.id.imageButtonAdd);
    recyclerViewAddresses = view.findViewById(R.id.recyclerViewAddresses);

    //Populate RecyclerView Addresses
    accountViewModel.init("Test");
    recyclerViewAddresses.setLayoutManager(new LinearLayoutManager(getContext(), LinearLayoutManager.VERTICAL, false));
    addressRecyclerViewAdapter = new AddressRecyclerViewAdapter(accountViewModel.getContactAddresses().getValue());
    recyclerViewAddresses.setAdapter(addressRecyclerViewAdapter);
    accountViewModel.getContactAddresses().observe(getActivity(), new Observer<ArrayList<ContactAddress>>() {
        @Override
        public void onChanged(ArrayList<ContactAddress> contactAddresses) {
            addressRecyclerViewAdapter.notifyDataSetChanged();
        }
    });

    imageButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            NavDirections action = AccountContactAddressFragmentDirections.actionAccountContactAddressFragmentToAccountContactAddressAddFragment();
            Navigation.findNavController(view).navigate(action);
        }
    });
}

}

RecyclerView Adapter:

public class AddressRecyclerViewAdapter extends RecyclerView.Adapter<AddressRecyclerViewAdapter.ViewHolder> {

    ArrayList<ContactAddress> contactAddressArrayList;

    public AddressRecyclerViewAdapter(ArrayList<ContactAddress> contactAddressArrayList){
        this.contactAddressArrayList = contactAddressArrayList;
    }

    @NonNull
    @Override
    public AddressRecyclerViewAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.recycler_view_addresses, parent, false);

        return new AddressRecyclerViewAdapter.ViewHolder(view);
    }

    @SuppressLint("SetTextI18n")
    @Override
    public void onBindViewHolder(@NonNull AddressRecyclerViewAdapter.ViewHolder holder, int position) {
        holder.textAddress.setText(contactAddressArrayList.get(position).getAddress());
        holder.textName.setText(contactAddressArrayList.get(position).getName());
        holder.textPhone.setText(contactAddressArrayList.get(position).getPhone());
    }

    @Override
    public int getItemCount() {
        return contactAddressArrayList == null ? 0 : contactAddressArrayList.size();
    }

    public static class ViewHolder extends RecyclerView.ViewHolder{

        TextView textAddress, textName, textPhone;

        public ViewHolder(@NonNull View itemView) {
            super(itemView);

            textName = itemView.findViewById(R.id.textName);
            textPhone = itemView.findViewById(R.id.textPhone);
            textAddress = itemView.findViewById(R.id.textAddress);
        }
    }
}

ViewModel:

public class AccountViewModel extends ViewModel {

    //Variables
    public MutableLiveData<ArrayList<ContactAddress>> contactAddresses;

    public void init(String userToken){
        contactAddresses = FirebaseHelper.getContactAddresses(userToken);
    }

    public MutableLiveData<ArrayList<ContactAddress>> getContactAddresses() {
        return contactAddresses;
    }
}

Repository:

public class FirebaseHelper {

    //Firebase Realtime Database Initialize
    private static DatabaseReference mDatabase = FirebaseDatabase.getInstance().getReference();

    //Variables
    private static MutableLiveData<ArrayList<ContactAddress>> contactAddresses = new MutableLiveData<>();

    //Get Contact Addresses
    public static MutableLiveData<ArrayList<ContactAddress>> getContactAddresses(String userToken){

        //Initialize Temporary List
        ArrayList<ContactAddress> tempContactAddresses = new ArrayList<>();

        //Getting the List
        mDatabase.child("ContactAddress").child(userToken).addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot snapshot) {
                tempContactAddresses.clear();

                //Iterate Contact Addresses
                for (DataSnapshot postSnapshot: snapshot.getChildren()) {
                    tempContactAddresses.add(postSnapshot.getValue(ContactAddress.class));
                }

                //Assign the New List
                contactAddresses.postValue(tempContactAddresses);
            }

            @Override
            public void onCancelled(@NonNull DatabaseError databaseError) {

            }
        });

        return contactAddresses;
    }
}

Solution

  •  accountViewModel.getContactAddresses().observe(getActivity(), new Observer<ArrayList<ContactAddress>>() {
            @Override
            public void onChanged(ArrayList<ContactAddress> contactAddresses) {
                addressRecyclerViewAdapter.notifyDataSetChanged();
            }
        });
    

    Here it seems like you haven't added new data to the adapter, try updating the adapter and call notifydatasetchanged