使用 LiveData 从片段内部操作 RecyclerView 中的数据

Using LiveData to manipulate data in RecyclerView from inside a Fragment

我在 Fragment 中有一个 RecyclerView,我想使用 MutableLiveData 填充数据。我有一个模拟 DAO returns 我模型的对象列表 class。 RecyclerView 执行时为空白。

这是我的模拟 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;
    }
}

这是我的 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;
    }
}

这是我的 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;
            }
        }
    }

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

我认为来自 DAO 的数据无法以某种方式传输到 RecyclerViewAdapter。我关注了 this blog.
如何使用 LiveData

使来自 DAO 的数据在 RecyclerView 中可见

编辑:
我根据 的回答更改了我的 ViewModel class。但是我的应用程序突然终止,没有任何错误或警告消息。当我调试时,我发现我的应用程序在执行以下行时崩溃:friendsModelLiveData.postValue(new DaoMockFriends().getFriendsList());

编辑2:
我在我的 ViewModel 实现 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);
            }
        });
    }  

应用程序在此 ArrayList<FriendsModel> fm = anInterface.getFriendsList(); 行突然终止。我跟着 线程提出了这种方法。

方法 new DaoMockFriends().getFriendsList() 永远不会执行,因为您已经在声明时初始化了 friendsModelLiveData

更新:

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