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;
}
}
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