MVVM Набор Recyclerview Адаптер с элементами во фрагменте - PullRequest
1 голос
/ 17 марта 2019

Я впервые использую шаблон 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());
        }
    });

}

}

и код адаптера:

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

}
}

Отображение действий утилита-ретранслятора было простым, но я не уверен, что делать с сессиями. Я следовал этой серии учебных пособий , но я застрял, как получить данные из viewmodel в просмотр повторного фрагмента. Я читал, что добавление виджетов в viewmodel может вызвать утечки памяти. Есть какой-либо способ сделать это? Спасибо.

1 Ответ

2 голосов
/ 17 марта 2019

Вы можете использовать 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);
            }
        });
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...