MVVM 设置 Recyclerview 适配器,其中包含片段中的项目

Dar*_*ris 5 android mvvm android-fragments android-recyclerview

我第一次使用 MVVM 模式与改造和回收视图。我已经在我的 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());
        }
    });

}

}
Run Code Online (Sandbox Code Playgroud)

和适配器代码:

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

}
Run Code Online (Sandbox Code Playgroud)

在我的片段中我有这个:

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) {

}
}
Run Code Online (Sandbox Code Playgroud)

显示 recyclerview 的操作很简单,但我不确定如何进行会话。我已经遵循了本教程系列,但我一直困惑如何将数据从视图模型获取到片段回收器视图中。我读过,将视图小部件添加到视图模型中可能会导致内存泄漏。有什么办法可以做到这一点吗?谢谢。

Bir*_*ani 5

您可以将 LiveData 用于此类目的。LiveData 具有生命周期感知能力,可以在 ViewModel 中使用。

在您的 中ViewModel,添加 type 属性MutableLiveData

private MutableLiveData<List<Session>> sessionsLiveData = new MutableLiveData<List<Session>>();

public LiveData<List<Session>> getSessionLiveData(){
    return sessionsLiveData;
}
Run Code Online (Sandbox Code Playgroud)

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());
        }
    });
Run Code Online (Sandbox Code Playgroud)

在您的片段中,观察 this 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);
            }
        });
Run Code Online (Sandbox Code Playgroud)