【问题标题】:Issues adding custom layout within each Recycler view在每个 Recycler 视图中添加自定义布局的问题
【发布时间】:2020-10-10 17:21:30
【问题描述】:

我正在构建一个应用程序,发布者将问题上传到数据库。发布者可以添加他们想要的任意数量的问题,所以我使用了回收站视图来处理这个问题。当发布者单击按钮添加问题时,新布局将按照我的 recyclerview 适配器中的指定进行膨胀。 TopicQuestionsAdapter 是我的回收器视图适配器的名称

                             ...

RecyclerView addTopicOfTheDayWhereDynamicLayoutsWillBeAdded;
TopicQuestionsAdapter topicQuestionsAdapter;
ArrayList<TopicQuestions> topicQuestionsList;

addTopicOfTheDayWhereDynamicLayoutsWillBeAdded.setHasFixedSize(true);
addTopicOfTheDayWhereDynamicLayoutsWillBeAdded.setLayoutManager(new LinearLayoutManager(getContext(), LinearLayoutManager.VERTICAL, false));
topicQuestionsList = new ArrayList<>();

                              ...

addTopicOfTheDayAddQuiz.setOnClickListener(v29 -> {

                              ...

            // dynamically add questions layout on subsequent clicks
            // here with an x button in each layout to remove the
            // entire question layout

            topicQuestionsList.add(new TopicQuestions());
            topicQuestionsAdapter = new TopicQuestionsAdapter("Adapter", getContext(), topicQuestionsList);
            addTopicOfTheDayWhereDynamicLayoutsWillBeAdded.setAdapter(topicQuestionsAdapter);
            topicQuestionsAdapter.notifyItemInserted(topicQuestionsList.size());

        }
    });

现在回收站视图布局由四个 FAB 组成,用于添加不同类型的问题和选项,一个文本视图和一个图像按钮用于删除整个视图

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TopicQuestionsViewHolder {
//R.layout.add_question_layout is the layout
    val itemView = LayoutInflater.from(parent.context).inflate(R.layout.add_question_layout, parent, false)
    return TopicQuestionsViewHolder(itemView)
}

/*this is where my problem is i observed that whenever i
    add a new question, the layouts i had already added to previous
    views get cleared. Recycler view destroys states*/

 override fun onBindViewHolder(holder: TopicQuestionsViewHolder, position: Int) {
    
    // the textview to show this question number
    holder.questionNumber.text = "${position + 1}."

    // the image button to remove the whole view
    holder.removeQuestion.setOnClickListener {
        topicQuestions.removeAt(position)
        notifyItemRemoved(position)
        notifyItemRangeChanged(position, topicQuestions.size)
    }

    holder.addField.setOnClickListener {
        // need to fix this
        when (holder.theFields.visibility == View.GONE) {
            true -> {
                holder.theFields.visibility = View.VISIBLE
                holder.addField.setImageResource(R.drawable.close)
                Log.wtf(TAG, "true")
            }
            false -> {
                holder.theFields.visibility = View.GONE
                holder.addField.setImageResource(R.drawable.add)
                Log.wtf(TAG, "false")
            }
        }
    }

    // this button would add a question field to this view
    holder.addQuestionField.setOnClickListener {
        val lParams = LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
        lParams.topMargin = 16
        val view = LayoutInflater.from(ctx).inflate(R.layout.add_question_field_to_question_layout, null)
        view.layoutParams = lParams
        holder.toAddViews.addView(view)
    }

    // this button would add an image question field to this view
    holder.addImageQuestionField.setOnClickListener {
        Log.wtf(TAG, "image question will be added here")
    }

    // this button would add toggle option to this view
    holder.addToggleOption.setOnClickListener {
        Log.wtf(TAG, "toggle option will be added here")
    }

    // this button would add check box option to this view
    holder.addCheckBoxOption.setOnClickListener {
        Log.wtf(TAG, "check box option will be added here")
    }
}

正如我之前在代码中所暗示的那样,每当我单击 addTopicOfTheDayAddQuiz 按钮时,该按钮应该在已经退出的视图下方添加另一个视图,现有视图中的所有子视图都将被清除。请问有什么更好的方法来解决这个问题?

【问题讨论】:

    标签: java android kotlin android-recyclerview


    【解决方案1】:

    您的适配器在 onBindViewHolder() 中做了很多工作:设置大量点击侦听器,这些侦听器依次切换 UI,以便用户可以输入他们的问题详细信息,而不会被他们不需要的 UI 元素打扰。

    但是您似乎没有在任何地方跟踪用户为每个问题所做的选择。 并且每次用户添加新问题时,您都会丢弃现有的适配器:

    topicQuestionsAdapter = new TopicQuestionsAdapter("Adapter", getContext(), topicQuestionsList); addTopicOfTheDayWhereDynamicLayoutsWillBeAdded.setAdapter(topicQuestionsAdapter);

    由于您没有为我提供足够的代码来调试您的应用程序和测试我的解决方案,所以我将简要介绍一些想法:

    不用每次创建新问题时都使用新的适配器,只需将问题添加到列表中,然后调用(请注意:topicQuestionsList.size()- 1

    topicQuestionsAdapter.notifyItemInserted(topicQuestionsList.size() - 1);
    

    您需要做的另一件事是跟踪每个列表项的状态(Buttons 等是可见的,EditTexts 的内容是什么,如果有的话...)。如果列表变长并且用户需要滚动,onBindViewHolder() 将被重复调用,即使您继续使用同一个 Adapter。

    所以你需要一个类——我们称之为ListEntry——带有反映列表项可能状态的字段。在适配器内部,您可以为数据列表的每个项目保留一个List&lt;ListEntry&gt; 和一个ListEntry。每次某些Button 变得可见时,您都会更新相应的ListEntry。在onBindViewHolder() 中,您评估给定位置的ListEntry,并相应地设置holder.itemView 的子Views 的属性。

    【讨论】:

    • 谢谢。如果可以的话,我会喜欢一个 sn-p 的代码。它会帮助我更好地了解你?
    • 我会更新这个,这样你就可以看到代码的重要部分。尤其是我的 POJO 类,TopicQuestions
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多