Shankha057
Shankha057

Reputation: 1369

Using LiveData to manipulate data in RecyclerView from inside a Fragment

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

Answers (1)

Yogesh Lakhotia
Yogesh Lakhotia

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

Related Questions