使用 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;
}
}
我在 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
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;
}
}