Reputation: 1369
I have a RecyclerView
in a Fragment
where I would like to populate data using MutableLiveData
. I have a mock DAO that returns a list of objects of my Model class. The RecyclerView
is blank when executed.
This is my mock DAO
class:
public class DaoMockFriends implements DaoFriendsInterface {
private ArrayList<FriendsModel> friendsModelsArrayList;
public DaoMockFriends() {
friendsModelsArrayList = new ArrayList<>();
}
@SuppressLint("NewApi")
@Override
public List<FriendsModel> getFriendsList() {
for(int i = 0 ; i < 10 ; i++){
FriendsModel friendsModel = (new FriendsModel("adasdsada"+i,"sdadsadsa"+(i*2),"adsdsadssad"+(i*3),""+(i++), LocalDateTime.now()));
friendsModelsArrayList.add(friendsModel);
}
return friendsModelsArrayList;
}
}
This is my ViewModel
class:
import android.arch.lifecycle.LiveData;
import android.arch.lifecycle.MutableLiveData;
import android.arch.lifecycle.ViewModel;
import java.util.List;
public class FriendsListLiveDataProvider extends ViewModel {
private MutableLiveData<List<FriendsModel>> friendsModelLiveData = new MutableLiveData<>();
public LiveData<List<FriendsModel>> getFriendsModelLiveData() {
if(this.friendsModelLiveData == null) friendsModelLiveData.postValue(new DaoMockFriends().getFriendsList());
return this.friendsModelLiveData;
}
}
This is my RecyclerViewAdapter
class:
public class AdapterFriendsListRecyclerView extends RecyclerView.Adapter<AdapterFriendsListRecyclerView.ViewHolder> {
private List<FriendsModel> listOfFriends;
public AdapterFriendsListRecyclerView(List<FriendsModel> listOfFriends) {
this.listOfFriends = listOfFriends;
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return new ViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.friend_entiry_block,parent,false));
}
@SuppressLint("SetTextI18n")
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
FriendsModel friendsInterface = this.listOfFriends.get(position);
String firstName = friendsInterface.getFirstName();
String lastName = friendsInterface.getLastName();
holder.getTextView().setText(firstName+" "+lastName);
}
@Override
public int getItemCount() {
return listOfFriends.size();
}
public void addItems(List<FriendsModel> friendsInterface){
this.listOfFriends = friendsInterface;
notifyDataSetChanged();
}
public static class ViewHolder extends RecyclerView.ViewHolder {
private TextView textView;
public ViewHolder(View itemView) {
super(itemView);
this.textView = itemView.findViewById(R.id.friendEntityNameTV);
}
public TextView getTextView() {
return textView;
}
}
}
This is the implementation in the Fragment
:
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View v = inflater.inflate(R.layout.fragment_friends_list, container, false);
friendsListRV = v.findViewById(R.id.FriendsListRecyclerView);
adapterFriendsListRecyclerView = new AdapterFriendsListRecyclerView(new ArrayList<>());
friendsListRV.setLayoutManager(new LinearLayoutManager(getActivity()));
friendsListRV.setAdapter(adapterFriendsListRecyclerView);
friendsListLiveDataProvider = ViewModelProviders.of(this).get(FriendsListLiveDataProvider.class);
friendsListLiveDataProvider
.getFriendsModelLiveData()
.observe(this, (friendsModels) -> adapterFriendsListRecyclerView
.addItems(friendsModels));
return v;
}
I think that somehow the data from the DAO isn't getting across to the RecyclerViewAdapter
. I followed this blog.
How to make the data from the DAO visible in the RecyclerView
using LiveData
EDIT:
I changed my ViewModel
class as per Yogesh's answer. But my app terminates abruptly without any error or warning messages. When I debug, I found that my app crashes on execution of this line: friendsModelLiveData.postValue(new DaoMockFriends().getFriendsList());
EDIT2:
I tried with the code below in my ViewModel
implementation class
public LiveData<List<FriendsModel>> getFriendsModelLiveData() {
if(friendsModelLiveData == null){
friendsModelLiveData = new MutableLiveData<>();
}
loadData();
return this.friendsModelLiveData;
}
private void loadData(){
DaoMockFriends anInterface = new DaoMockFriends();
ArrayList<FriendsModel> fm = anInterface.getFriendsList();
ExecutorService executorService = Executors.newSingleThreadExecutor();
executorService.submit(new Runnable() {
@Override
public void run() {
friendsModelLiveData.postValue(fm);
}
});
}
The app abruptly terminates at this ArrayList<FriendsModel> fm = anInterface.getFriendsList();
line. I followed this thread to come up with this type of approach.
Upvotes: 0
Views: 3634
Reputation: 888
Method new DaoMockFriends().getFriendsList()
never gets executed, because you have initialized friendsModelLiveData
at declaration.
Update:
public class FriendsListLiveDataProvider extends ViewModel {
private MutableLiveData<List<FriendsModel>> friendsModelLiveData;
public LiveData<List<FriendsModel>> getFriendsModelLiveData() {
if(this.friendsModelLiveData == null) {
friendsModelLiveData = new MutableLiveData<>();
friendsModelLiveData.postValue(new DaoMockFriends().getFriendsList());
}
return this.friendsModelLiveData;
}
}
Upvotes: 3