Moxy icon indicating copy to clipboard operation
Moxy copied to clipboard

Is it realistic to use moxy for viewholders in recyclerview? Have a sample?

Open noname-developer opened this issue 3 years ago • 1 comments

I have created a presenter for the view holder to display it correctly according to the data. But now, unfortunately, you have to do it in the classic way without moxy. I tried to make the view holder as a custom view, but it has no lifecycle. Tell me, is there a way to work with recyclerview adapter and its view holders using moxy? :)

TaskAdapter:

public class TaskAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

    private static final int VIEW_TASK = 1;
    private static final int VIEW_HEADER_COMPLETED_TASKS = 2;
    private static final int VIEW_COMPLETED_TASKS = 3;
    private final TasksPresenter presenter;
    private List<Task> taskList;

    public TaskAdapter(TasksPresenter presenter) {
        this.presenter = presenter;
        taskList = new ArrayList<>();
    }

    @NonNull
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View v;
        switch (viewType) {
            case VIEW_TASK:
                v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_task, parent, false);
                return new TaskViewHolder(v);
		...
    }

    @Override
    public int getItemViewType(int position) {
        if (taskList.get(position).isComplete())
            return VIEW_COMPLETED_TASKS;
		...
    }

    @Override
    public void onBindViewHolder(@NonNull final RecyclerView.ViewHolder holder, final int position) {
        if (getItemViewType(position) == VIEW_TASK) {
            TaskViewHolder taskViewHolder = (TaskViewHolder) holder;
            taskViewHolder.bind(taskList.get(position), presenter);
        }
		...
    }

    public List<Task> getData() {
        return taskList;
    }

    public void setData(List<Task> taskList) {
        this.taskList = taskList;
    }

    @Override
    public int getItemCount() {
        return taskList.size();
    }
		...
}

TaskViewHolder:

public class TaskViewHolder extends RecyclerView.ViewHolder implements TaskMvpHolder.view {

    private final DateDisplay display;
    private TaskViewHolderPresenter holderPresenter;
    private LinearLayout dateHolder;
    private TextView titleHolder, textHolder, dateTextHolder;
    private CheckBox checkBoxHolder;
    private ImageView priorityHolder;

    public TaskViewHolder(View itemView) {
        super(itemView);
        holderPresenter = new TaskViewHolderPresenter(this);
   		...
    }

    public void bind(@NonNull Task task, TasksMvp.presenter tasksPresenter) {
        holderPresenter.onBind(task);

        itemView.setOnClickListener(v -> tasksPresenter.onTaskItemClick(task.getId()));

        checkBoxHolder.setOnClickListener(v -> tasksPresenter.onTaskItemCheckboxClick(task.getId()));
    }

    @Override
    public void showTitle(String title) {
        titleHolder.setText(title);
    }

    @Override
    public void showText(String text) {
        textHolder.setText(text);
        textHolder.setVisibility(View.VISIBLE);
    }

    @Override
    public void hideText() {
        textHolder.setVisibility(View.GONE);
    }

    @Override
    public void showReminder(Calendar cal, String time) {
		...
        dateTextHolder.setVisibility(View.VISIBLE);
    }

    @Override
    public void hideReminder() {
        dateHolder.setVisibility(View.GONE);
    }

    @Override
    public void showPriority() {
		...
    }

    @Override
    public void hidePriority() {
        priorityHolder.setVisibility(View.GONE);
    }
}

TaskViewHolderPresenter:

public class TaskViewHolderPresenter implements TaskMvpHolder.presenter {

    TaskMvpHolder.view view;

    public TaskViewHolderPresenter(TaskMvpHolder.view view) {
        this.view = view;
    }

    @Override
    public void onBind(@NonNull Task task) {
        String title = task.getTitle();
        String text = task.getText();
        String date = task.getDate();
        String time = task.getTime();
        Calendar cal = Calendar.getInstance();
        int priority = task.getPriority();

        view.showTitle(title);

        if (!text.equals("")) {
            view.showText(text);
        } else view.hideText();

        if (!date.equals("")) {
		...
            view.showReminder(cal, time);
        } else view.hideReminder();

        if (priority != 0) {
            view.showPriority();
        } else view.hidePriority();
    }
}

I hope the example is readable :)

noname-developer avatar Aug 31 '20 17:08 noname-developer

Yes, this is possible, and I know some guys doing it. Unfortunately, I have no sample, so you should ask or search in https://t.me/moxy_ru chat, I'm sure it was discussed there.

alaershov avatar Aug 31 '20 17:08 alaershov