我第一次将MVVM模式与改造和recyclerview一起使用。我已经在viewmodel类中进行了网络调用,但是不知道如何在recyclerview中显示数据。
这是我的视图模型代码:
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();
}
}
在我的片段中,我有这个:
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很简单,但是我不确定如何进行会话。我已经遵循this tutorial series的问题,但是我仍然停留在如何将数据从viewmodel获取到片段recyclerview中的问题。我已经读过,将视图小部件添加到viewmodel中会导致内存泄漏。有什么办法吗?谢谢。
答案 0 :(得分:1)
您可以将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());
}
});
在您的片段中,观察此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);
}
});