Home > Enterprise >  Changing 1 value of an arrays makes the other values null
Changing 1 value of an arrays makes the other values null

Time:06-16

I have multiple edit text in a recycler view which is placed inside another recycler view. When I change the text of that recycler view, I send the interface event to the parent recycler view. This is how the interface callback looks:

override fun onOptionTextChanged(position: Int, text: String) {
   val oldOptions = questions[holder.adapterPosition].options.copyOf()
   Log.d(TAG, "onOptionTextChanged: oldOptions: ${oldOptions.contentToString()}")
   questions[holder.adapterPosition].options = arrayOfNulls(questionOptionAddList.size)
   for (oldDataIndex in oldOptions.indices){
      questions[holder.adapterPosition].options[oldDataIndex]?.text = oldOptions[oldDataIndex]!!.text
   }
   questions[holder.adapterPosition].options[position] = QuestionOptionAdd(text = text)
   Log.d(TAG, "onOptionTextChanged: newOptions: ${questions[holder.adapterPosition].options.contentToString()}")
}

But I get a weird issue. Whenever I change the value of 1 edit text, the other values go to null. So, I tried checking the old and new arrays which I created and then got this in my log:

D/AddFormQuestionsAdapter: onOptionTextChanged: oldOptions: []
D/AddFormQuestionsAdapter: onOptionTextChanged: newOptions: [QuestionOptionAdd(text=n, hasImage=false, imageUrl=), null]
D/AddFormQuestionsAdapter: onOptionTextChanged: oldOptions: [QuestionOptionAdd(text=n, hasImage=false, imageUrl=), null]
D/AddFormQuestionsAdapter: onOptionTextChanged: newOptions: [QuestionOptionAdd(text=no, hasImage=false, imageUrl=), null]

// from here, I started to write in the other edit text

D/AddFormQuestionsAdapter: onOptionTextChanged: oldOptions: [QuestionOptionAdd(text=no, hasImage=false, imageUrl=), null]
D/AddFormQuestionsAdapter: onOptionTextChanged: newOptions: [null, QuestionOptionAdd(text=y, hasImage=false, imageUrl=)]
D/AddFormQuestionsAdapter: onOptionTextChanged: oldOptions: [null, QuestionOptionAdd(text=y, hasImage=false, imageUrl=)]
D/AddFormQuestionsAdapter: onOptionTextChanged: newOptions: [null, QuestionOptionAdd(text=ye, hasImage=false, imageUrl=)]
D/AddFormQuestionsAdapter: onOptionTextChanged: oldOptions: [null, QuestionOptionAdd(text=ye, hasImage=false, imageUrl=)]
D/AddFormQuestionsAdapter: onOptionTextChanged: newOptions: [null, QuestionOptionAdd(text=yes, hasImage=false, imageUrl=)]

// from here, I started to write in the other edit text

D/AddFormQuestionsAdapter: onOptionTextChanged: oldOptions: [null, QuestionOptionAdd(text=yes, hasImage=false, imageUrl=)]
D/AddFormQuestionsAdapter: onOptionTextChanged: newOptions: [QuestionOptionAdd(text=no , hasImage=false, imageUrl=), null]

How can I prevent this?

CodePudding user response:

It's because you're doing this

// I'm pulling this out so it's not constantly repeated, it's just easier to read!
val question = questions[holder.adapterPosition]

// wipe all the options to null
question.options = arrayOfNulls(questionOptionAddList.size)
// iterate over all the old options you copied
for (oldDataIndex in oldOptions.indices){
    // copy the text to the option in the same position, unless it's null -
    // they're all null though, you just set it to a null array, so this does nothing!
    question.options[oldDataIndex]?.text = oldOptions[oldDataIndex]!!.text
}
// create a new item at the position you're editing - so you end up with one item
// in an array of nulls
question.options[position] = QuestionOptionAdd(text = text)

So you're basically clearing everything to null, trying to copy your text back to your null objects (which you can't, they're gone) and then adding one new item back in.

Honestly I'm not sure why you're doing this? Why do you need to copy the original data, wipe it, then copy it back again? Can't you just do something like this?

override fun onOptionTextChanged(position: Int, text: String) {
    // grab the current data, or create (and add) a new one if it's null
    val options = questions[holder.adapterPosition].options
    val questionOption = options[position]
        ?: QuestionOptionAdd().also { options[position] = it }
    // set the text on the object
    questionOption.text = text
}
 

CodePudding user response:

questions[holder.adapterPosition].options[oldDataIndex]?.text = oldOptions[oldDataIndex]!!.text

this doesn't do anything because you try to set the text on something that is null.

I believe maybe you want this:

questions[holder.adapterPosition].options[oldDataIndex] = oldOptions[oldDataIndex]
  • Related