moxy-community / Moxy

Moxy is MVP library for Android with incremental annotation processor and ktx features
MIT License
324 stars 33 forks source link

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

Open noname-developer opened 4 years ago

noname-developer commented 4 years ago

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

alaershov commented 4 years ago

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.