MVVM设置带有片段中项目的Recyclerview适配器

时间:2019-03-17 06:40:14

标签: android android-fragments mvvm android-recyclerview

我第一次将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中会导致内存泄漏。有什么办法吗?谢谢。

1 个答案:

答案 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);
            }
        });