Модифицируйте адаптер RecyclerView, чтобы показать разные макеты - PullRequest
0 голосов
/ 29 апреля 2020

Я пытаюсь создать опрос и отобразить вопросы в программе recyclerView, но все типы вопросов имеют разные макеты. Как отобразить правильный макет в зависимости от типа вопроса?

Вопросы имеют метод с именем getResponse_type_id, который возвращает число от 1 до 4, которое является типом вопроса. Как мне изменить адаптер, чтобы сделать это возможным.

Мой адаптер сейчас супер базовый c, это то, что у меня есть

public class SurveyQuestionsAdapter extends RecyclerView.Adapter<SurveyQuestionsAdapter.QuestionViewHolder> {
    private ArrayList<SurveyQuestions> mQuestionList;

    public static class QuestionViewHolder extends RecyclerView.ViewHolder {
        public TextView questionTitle;
        public TextView questionOptional;
        public TextView questionInstructions;

        public QuestionViewHolder(@NonNull View itemView) {
            super(itemView);

            //these are shared fields in all the question type layouts
            questionTitle = itemView.findViewById(R.id.question_name);
            questionOptional = itemView.findViewById(R.id.question_optional);
            questionInstructions = itemView.findViewById(R.id.question_instructions);


        }
    }

    public SurveyQuestionsAdapter(ArrayList<SurveyQuestions> questions) {
        mQuestionList = questions;
    }

    @NonNull
    @Override
    public QuestionViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        //this is where the layout gets passed but how can I do it depending on the question type here
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout., parent, false);
        QuestionViewHolder qvh = new QuestionViewHolder(view);

        return qvh;
    }

    @Override
    public void onBindViewHolder(@NonNull QuestionViewHolder holder, int position) {
        SurveyQuestions current = mQuestionList.get(position);

        //I can get the question type here like this current.getResponse_type_id()
    }

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

У вопросов есть эта информация при отправке к адаптеру это список вопросов, ниже один вопрос.

{
      "id": 1,
      "question": "asdf",
      "instruction": "asdf",
      "response_type_id": 1,
      "optional": 0,
      "num": null,
      "rank": null,
      "show_text": null,
      "pivot": {
        "survey_id": 1,
        "survey_question_id": 1,
        "order": 0
      },
      "survey_question_option": []
    },

Ответы [ 2 ]

0 голосов
/ 29 апреля 2020

[репост из моего ответа на Reddit - вы сказали, что вас это смутило - можете ли вы рассказать, какие части вас смутили?]

Мы делаем нечто подобное ...

Это хорошо работает для нас. Мы создали класс «виджетов» для каждого типа отображаемых объектов - это будут ваши типы вопросов (я рекомендую создать базовый класс Question) - это строго данные, без ссылок Android. Вы создадите список из них, чтобы представить форму на экране, и передадите этот список адаптеру переработчика просмотра (я опишу его ниже).

Назначьте каждому типу вопроса уникальное целое число; это будет тип представления элемента, используемый в адаптере.

Затем создайте подкласс RecyclerView.ViewHolder, который имеет функцию связывания, которая примет ваш тип вопроса. Что-то вроде

абсолютный класс QuestionViewHolder: ViewHolder {abstract fun bind (question: QUESTION_TYPE)} *

Затем создайте подкласс QuestionViewHolder для каждого типа данных (передав его в качестве квалификатора типа), с соответствующий макет для каждого. Держатель представления должен иметь функцию связывания, которая будет передавать объект вопроса и устанавливать данные в макете. Затем держатель представления может обновлять данные в объекте вопроса, когда пользователь вносит изменения.

Создание адаптера для представления переработчика. Ключевым моментом здесь является реализация getItemViewType (int) - вы посмотрите, какой вопрос находится на этой позиции, и вернете целое число, представляющее тип вопроса. Вам нужно будет указать тип держателя вида, возможно, QuestionViewHolder (возможно, вам придется поиграться с обобщенными типами c, как только вы начнете ... Если генерики вызывают проблемы, и они могут b / c, то это дисперсию "in", отбросьте тип generi c в QuestionViewHolder, передав в параметре Question функцию Bind, и приведите его к типу, необходимому для каждого подкласса ... Мне пришлось поиграть с нашим довольно немного, чтобы обобщить все классы - это может не стоить усилий, и вы можете просто привести функцию bind ...)

В onCreateViewHolder адаптера создайте экземпляр ViewHolder, который соответствует Передан itemViewType.

В адаптере onBindViewHolder просто найдите вопрос для отображения и передайте его функции связывания, созданной вами в держателе представления.

И в этом суть .. .

Другой вариант - просто создать представления и добавить их в длинный LinearLayout, но если форма длинная, производительность может быть плохой - вид переработчика хорош b / c, он может использовать одни и те же блоки вопросов.

Удачи!

0 голосов
/ 29 апреля 2020

Вы должны использовать мощность ViewHolderTypes . Вы должны создать 4 виджетов, каждый видхолдер представляет тип вопроса.

отметьте в этой статье , в которой разъясняется, как использовать разные viewTypes в recyclerView.

Надеюсь, это поможет

Счастливое кодирование 101

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...