我第一次使用 MVVM 模式与改造和回收 View 。我已经在我的 viewmodel 类中进行了网络调用,但不知道如何在 recyclerview 中显示数据。
这是我的 View 模型代码:
public class HomeSessionsViewModel extends ViewModel {
private static final String TAG = HomeSessionsViewModel.class.getSimpleName();
private Context context;
public String sessionImg;
public String title, programName, batchName, batchPlayersCount;
public HomeSessionsViewModel(Context context) {
this.context = context;
}
public void fetchSessions(String coachId){
Log.d(TAG, "Call made");
Call<SessionDetails> call = RestClient.getRestInstance()
.getSessionsService()
.fetchSessions(coachId);
call.enqueue(new Callback<SessionDetails>() {
@Override
public void onResponse(Call<SessionDetails> call, Response<SessionDetails> response) {
if (response.isSuccessful()){
SessionDetails details = response.body();
List<Sessions> sessions = details.getSessions();
for (int i = 0; i < sessions.size(); i++){
Log.d(TAG, "Session Name:\t" + sessions.get(i).session_name);
sessionImg = sessions.get(i).sessionImage;
title = sessions.get(i).session_name;
programName = sessions.get(i).program_name;
batchName = sessions.get(i).batch_name;
batchPlayersCount = sessions.get(i).participants_count;
// addData(sessions);
}
}
}
@Override
public void onFailure(Call<SessionDetails> call, Throwable t) {
Log.d(TAG, "Can't Get Sessions:\n");
Log.d(TAG, t.getMessage());
}
});
}
}
和适配器代码:
public class SessionsAdapter extends RecyclerView.Adapter<SessionsViewHolder> {
private final Context context;
private List<HomeSessionsViewModel> itemsList;
public SessionsAdapter(Context context, List<HomeSessionsViewModel> itemsList) {
this.context = context;
this.itemsList = itemsList;
}
@Override
public SessionsViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
HomeSessionsBinding sessionsBinding = HomeSessionsBinding.inflate(inflater, parent, false);
return new SessionsViewHolder(sessionsBinding);
}
@Override
public void onBindViewHolder(SessionsViewHolder viewholder, int position) {
HomeSessionsViewModel viewModel = itemsList.get(position);
viewholder.bindSessions(viewModel);
}
@Override
public int getItemCount() {
if (itemsList == null) {
return 0;
}
return itemsList.size();
}
}
在我的 fragment 中我有这个:
public class HomeFragment extends Fragment implements OnItemClickedListener, DatePickerListener {
private RecyclerView actionsRV, sessionsRV;
private List<ActionsViewModel> actionsList = new ArrayList<>();
private ActionsAdapter actionsAdapter;
private HomeFragmentBinding fragmentBinding;
private HomeFragmentViewModel homeViewModel;
private HomeSessionsViewModel sessionsViewModel;
private List<HomeSessionsViewModel> sessionsViewModelList = new ArrayList<>();
private SessionsAdapter sessionsAdapter;
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
fragmentBinding = DataBindingUtil.inflate(inflater, R.layout.home_fragment, container, false);
homeViewModel = new HomeFragmentViewModel(getActivity());
fragmentBinding.setHomeViewModel(homeViewModel);
init();
return fragmentBinding.getRoot();
}
private void init() {
addActions();
initPicker();
populateSessions();
}
private void initPicker() {
fragmentBinding.datePicker.setListener(this)
.setMonthAndYearTextColor(getActivity().getResources().getColor(R.color.white))
.setDateSelectedColor(getActivity().getResources().getColor(R.color.white))
.setDateSelectedTextColor(getActivity().getResources().getColor(R.color.event_color_03))
.setTodayButtonTextColor(getActivity().getResources().getColor(R.color.white))
.setTodayDateTextColor(getActivity().getResources().getColor(R.color.accent))
.setUnselectedDayTextColor(getActivity().getResources().getColor(R.color.white))
.init();
}
private void populateSessions() {
sessionsViewModel = ViewModelProviders.of(this).get(HomeSessionsViewModel.class);
sessionsViewModel.fetchSessions("4086");
//sessionsViewModel.fetchSessions();
//sessionsViewModel.fetchSessions(""); // TODO: 3/16/2019 Use coach id from db
sessionsRV = fragmentBinding.sessionsRV;
//sessionsViewModelList = sessionsViewModel.items();
sessionsAdapter = new SessionsAdapter(getActivity(), sessionsViewModelList);
}
private void addActions() {
actionsRV = fragmentBinding.actionsRV;
actionsRV.setHasFixedSize(true);
LinearLayoutManager hlm = new LinearLayoutManager(getActivity(), LinearLayoutManager.HORIZONTAL, false);
fragmentBinding.actionsRV.setLayoutManager(hlm);
ActionsViewModel action1 = new ActionsViewModel();
action1.name = "Attendance";
action1.img = getResources().getDrawable(R.drawable.ic_attendance);
actionsList.add(action1);
ActionsViewModel action2 = new ActionsViewModel();
action2.name = "Evaluate";
action2.img = getResources().getDrawable(R.drawable.ic_evaluate);
actionsList.add(action2);
ActionsViewModel action3 = new ActionsViewModel();
action3.name = "Players";
action3.img = getResources().getDrawable(R.drawable.ic_players);
actionsList.add(action3);
ActionsViewModel action4 = new ActionsViewModel();
action4.name = "Programs";
action4.img = getResources().getDrawable(R.drawable.ic_programs);
actionsList.add(action4);
ActionsViewModel action5 = new ActionsViewModel();
action5.name = "Tips/VOD";
action5.img = getResources().getDrawable(R.drawable.ic_tips_vod);
actionsList.add(action5);
actionsAdapter = new ActionsAdapter(getActivity(), actionsList);
actionsAdapter.setItemClickedListener(this);
actionsRV.setAdapter(actionsAdapter);
}
@Override
public void itemClicked(int position) {
switch (position){
case 0:
Toast.makeText(getActivity(), "Attendance Clicked", Toast.LENGTH_SHORT).show();
break;
case 1:
Toast.makeText(getActivity(), "Evaluate Clicked", Toast.LENGTH_SHORT).show();
break;
case 2:
Toast.makeText(getActivity(), "Players Clicked", Toast.LENGTH_SHORT).show();
break;
case 3:
Toast.makeText(getActivity(), "Programs Clicked", Toast.LENGTH_SHORT).show();
break;
case 4:
Snackbar.make(getActivity().findViewById(android.R.id.content), "Tips Coming Soon", Snackbar.LENGTH_SHORT).show();
break;
}
}
@Override
public void onDateSelected(DateTime dateSelected) {
}
}
显示 recyclerview 操作很简单,但我不确定如何进行 session 。我已关注this tutorial series但我不知道如何将数据从 View 模型获取到 fragment 回收器 View 中。我读过,将 View 小部件添加到 View 模型中可能会导致内存泄漏。有什么办法可以做到这一点吗?谢谢。
最佳答案
您可以将 LiveData 用于此类目的。 LiveData 具有生命周期感知能力,可以在 ViewModel 中使用。
在您的 ViewModel
中,添加 MutableLiveData
类型的属性。
private MutableLiveData<List<Session>> sessionsLiveData = new MutableLiveData<List<Session>>();
public LiveData<List<Session>> getSessionLiveData(){
return sessionsLiveData;
}
当进行网络调用并且您拥有适配器所需的数据时,请为此 LiveData
设置值。
call.enqueue(new Callback<SessionDetails>() {
@Override
public void onResponse(Call<SessionDetails> call, Response<SessionDetails> response) {
if (response.isSuccessful()){
SessionDetails details = response.body();
List<Session> sessions = details.getSessions();
sessionsLiveData.postValue(sessions);
}
}
@Override
public void onFailure(Call<SessionDetails> call, Throwable t) {
Log.d(TAG, "Can't Get Sessions:\n");
Log.d(TAG, t.getMessage());
}
});
在您的 fragment 中,观察此LiveData
。
viewModel.getSessionLiveData().observe(this, new Observer<List<Session>>() {
@Override
public void onChanged(@Nullable final List<Session> sessions) {
// set Data to adapter here.
adapter.setData(sessions);
}
});
关于android - MVVM 设置 Recyclerview 适配器,其中包含 fragment 中的项目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55204497/