RecyclerView со списками переменного размера

Я разрабатываю проект для Android-курса и пытаюсь применить RecyclerView. Проект посвящен викторине, где у меня есть несколько вопросов, каждый с разными вариантами. У меня уже есть "рабочая" версия на github, но она реализована с помощью recyclerView внутри другого recyclerView, для вопросов и answerOptions соответственно. Я хочу изменить это, так как это кажется «странным».

Я мог бы легко создать макет для каждого вопроса, но я хочу сделать его более «общим». Я предполагаю, что у меня может быть, например, 100 вариантов в каждом вопросе. В этом случае я бы хотел повторить один и тот же шаблон для каждого варианта ответа. Я уже пробовал добавлять представления динамически, но я не так много узнал об этом, поэтому я немного потерялся. Пожалуйста, спросите меня обо всем, чего может не хватать, чтобы помочь вам помочь мне.

Заранее спасибо!

Полный "рабочий" проект здесь. Я пытаюсь избежать использования recyclerView внутри другого, но все же как-то «перерабатываю». https://github.com/Rheneni/QuizzApp_Udacity

Как я начинаю деятельность:

static final int QUESTIONS_NUMBER = 1;
private ArrayList<ArrayList<Integer>> mSolutions = new ArrayList<>();
private ArrayList<Integer> mOptionTypes = new ArrayList<>();
private ArrayList<Integer> mQuestionNumOptions = new ArrayList<>();
private RecyclerView mRecyclerView;
private ArrayList<Question> mQuestions = new ArrayList<>();
private QuestionAdapter mAdapter;
private int questionsCorrect = 0;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    fillLists();
    for(int i = 0; i < QUESTIONS_NUMBER; i++) {
        mQuestions.add(new Question(this, i+1, mOptionTypes.get(i), mQuestionNumOptions.get(i)));
    }

    setupRecycler();
}

private void setupRecycler() {
    mRecyclerView = (RecyclerView) findViewById(R.id.recycler_view_layout_recycler);

    LinearLayoutManager linearLayoutManager = new LinearLayoutManager(QuestionLayoutActivity.this);
    linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
    mRecyclerView.setLayoutManager(linearLayoutManager);

    mAdapter = new QuestionAdapter(this, mQuestions);

    mRecyclerView.setAdapter(mAdapter);
    mAdapter.notifyDataSetChanged();
    mRecyclerView.addItemDecoration(
            new DividerItemDecoration(this, DividerItemDecoration.VERTICAL));
}

Мой адаптер прямо сейчас (не работает) и выдает эту ошибку: java.lang.IllegalStateException: у указанного дочернего элемента уже есть родитель. Вы должны сначала вызвать removeView () для родительского элемента ребенка.

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

private static final int QUESTION_VIEW  = 1;
private static final int RADIO_OPTION_VIEW = 2;
private static final int CHECKBOX_OPTION_VIEW = 3;
private static final int FREE_ANSWER = 4;
private Context mContext;
private ArrayList<Question> mQuestions;
private RecyclerView mRecyclerView;

public QuestionAdapter(Context context, ArrayList<Question> questions) {
    mContext = context;
    if (questions != null)
        mQuestions = new ArrayList<>(questions);
    else mQuestions = new ArrayList<>();
}

public class ViewHolder extends RecyclerView.ViewHolder{
    public TextView questionNumber;
    public TextView questionText;
    public TextView radioOptionText;
    public RadioButton radioOption;
    public TextView checkBoxOptionText;
    public CheckBox checkBoxOption;
    public TextView freeText;

    public ViewHolder(final View itemView) {
        super(itemView);

        questionNumber = (TextView) itemView.findViewById(R.id.question_number);
        questionText = (TextView) itemView.findViewById(R.id.question);

        radioOption = (RadioButton)itemView.findViewById(R.id.option_radio);
        radioOptionText = (TextView)itemView.findViewById(R.id.option_text);

        checkBoxOption = (CheckBox)itemView.findViewById(R.id.option_checkbox);
        checkBoxOptionText = (TextView)itemView.findViewById(R.id.option_text);

        freeText = (TextView)itemView.findViewById(R.id.option_free);
    }

    public void bindRadioViewList(int pos){
        Log.d("tag", "pos:" + pos);
        Question question = mQuestions.get(pos);

        String message = question.getQuestionName();
        Log.d("tag", message);
        Log.d("tag", question.getQuestionName());
        Log.d("tag", question.getQuestionText());
        Log.d("tag", "" + question.getOptionsNumber());


        final String text = question.getAnswerOptions().get(0).getOptionText();
        final boolean isChecked = question.getAnswerOptions().get(0).getIsChecked();
        //questionNumber.setText(question.getQuestionName());
        //questionText.setText(question.getQuestionText());

        radioOptionText.setText(text);
        radioOption.setSelected(isChecked);
    }

    public void bindCheckBoxViewList(int pos){
        Log.d("tag", "pos:" + pos);
        Question question = mQuestions.get(pos);

        String message = question.getQuestionName();
        Log.d("tag", message);
        Log.d("tag", question.getQuestionName());
        Log.d("tag", question.getQuestionText());
        Log.d("tag", "" + question.getOptionsNumber());

        final String text = question.getAnswerOptions().get(0).getOptionText();
        final boolean isChecked = question.getAnswerOptions().get(0).getIsChecked();
        //questionNumber.setText(question.getQuestionName());
        //questionText.setText(question.getQuestionText());

        checkBoxOptionText.setText(text);
        checkBoxOption.setSelected(isChecked);
    }

    public void bindQuestionRadioViewList(int pos){
        Log.d("tag", "pos:" + pos);
        Question question = mQuestions.get(pos);

        String message = question.getQuestionName();
        Log.d("tag", message);
        Log.d("tag", question.getQuestionName());
        Log.d("tag", question.getQuestionText());
        Log.d("tag", "" + question.getOptionsNumber());

        final String text = question.getAnswerOptions().get(0).getOptionText();
        final boolean isChecked = question.getAnswerOptions().get(0).getIsChecked();
        questionNumber.setText(question.getQuestionName());
        questionText.setText(question.getQuestionText());

        radioOptionText.setText(text);
        radioOption.setSelected(isChecked);
    }
}

private class QuestionViewHolder extends ViewHolder{
    public QuestionViewHolder(View itemView){
        super(itemView);
    }
}

private class RadioViewHolder extends ViewHolder{
    public RadioViewHolder(View itemView){
        super(itemView);
    }
}

private class CheckBoxViewHolder extends ViewHolder{
    public CheckBoxViewHolder(View itemView){
        super(itemView);
    }
}

@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View v;
    if (viewType == RADIO_OPTION_VIEW) {
        //v = LayoutInflater.from(parent.getContext()).inflate(R.layout.question_radio_option, parent, false);
        //RadioViewHolder vh = new RadioViewHolder(v);
        LinearLayout questionLayout = (LinearLayout)LayoutInflater.from(parent.getContext()).inflate(R.layout.question, parent, false);
        if (questionLayout.getParent() != null) {
            ((ViewGroup)questionLayout.getParent()).removeView(questionLayout);
        }
        LinearLayout optionsLayout = (LinearLayout)LayoutInflater.from(parent.getContext()).inflate(R.layout.question_radio_option, parent, false);
        if (optionsLayout.getParent() != null) {
            ((ViewGroup)optionsLayout.getParent()).removeView(optionsLayout);
        }
        parent.addView(questionLayout);
        parent.addView(optionsLayout);
        View view = parent;
        QuestionViewHolder vh = new QuestionViewHolder(view);
        return vh;
    }
    else if (viewType == CHECKBOX_OPTION_VIEW) {
        v = LayoutInflater.from(parent.getContext()).inflate(R.layout.question_checkbox_option, parent, false);
        CheckBoxViewHolder vh = new CheckBoxViewHolder(v);
        return vh;
    }
    else {
        Log.d("tag", "viewType not found");
        v = LayoutInflater.from(parent.getContext()).inflate(R.layout.question_radio_option, parent, false);
        RadioViewHolder vh = new RadioViewHolder(v);
        return vh;
    }
}

@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
    try {
        if (holder instanceof QuestionViewHolder) {
            //RadioViewHolder vh = (RadioViewHolder) holder;
            //vh.bindRadioViewList(position);
            QuestionViewHolder vh = (QuestionViewHolder)holder;
            vh.bindQuestionRadioViewList(position);
        }
        else if (holder instanceof CheckBoxViewHolder) {
            CheckBoxViewHolder vh = (CheckBoxViewHolder) holder;
            vh.bindCheckBoxViewList(position);
        }
    } catch (Exception e) {
        e.printStackTrace();
    }

    Log.d("tag", "bind Done");
}

@Override
public int getItemCount() {
    int count = 0;
    if (mQuestions != null){
        count = mQuestions.size();
    }
    return count;
}

RecyclerView со списками переменного размера

попробуйте использовать RecyclerView развернуть / свернуть элементы

sanemars 21.03.2018 03:16

Вместо того, чтобы прокручивать вопросы вниз, почему бы не задать один вопрос на странице? так что параметры могут иметь вид ресайклера в макете программы просмотра страниц.

Satya 21.03.2018 03:34

@sanemars я проверю это

Rafael Lopes 21.03.2018 13:00

@Satya Идея заключалась в том, чтобы разрешить "прокрутку", а затем я бы добавил кнопку "Далее", чтобы можно было перейти непосредственно к следующим вопросам. Или даже «предыдущий».

Rafael Lopes 21.03.2018 13:01
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
4
133
0

Другие вопросы по теме