I have a dynamic list of input fields. Those. Depending on the user's choice of certain values, a list of input fields is displayed. So I had to add these fields (EditText) programmatically to an empty LinearLayout, which I specifically placed in the markup. The code is added at a certain moment (when the user in the spiner has selected the desired category). The code for creating input fields is:
fun generateAdditionalFields(fields: ArrayList<String>) { tempAdditionalFields.removeAll(tempAdditionalFields) var isFirst = true fields.forEach { tempAdditionalFields.add(makeEditText(it, it, isFirst)) isFirst = false } additional_fields_block.removeAllViews() tempAdditionalFields.forEach { additional_fields_block.addView(it) } } fun makeEditText(hint: String, name: String, first: Boolean) : EditText { val editText = EditText(ContextThemeWrapper(this, R.style.MainInput), null, 0) editText.hint = hint editText.layoutParams = LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT) editText.tag = name if (!first) editText.setMargin(topMargin = dpToPix(5f)) return editText } I also have a list for storing these tempAdditionalFields input fields so that you can later save the data entered by the user.
When a user switches a category, the old input fields are deleted (both from the list and from LinearLayout ) and generated again.
Everything worked without problems. But I decided to modify the code and save the data when the device's screen rotates, and restore it after the re-creation of the activation. Usually there are no problems with this operation. But in this case, after recreating the tempAdditionalFields , I restore the tempAdditionalFields list, and then from it I add all the EditText back to LinearLayout, but then it gives an error saying that they already contain these views. Then I call before adding additional_fields_block.removeAllViews() , and the same error still crashes. Then I removed the add. But the screen displays completely new input fields. Yes, these are the input fields that were before the re-creation of the activation, but without the text entered. Although in the restored tempAdditionalFields list tempAdditionalFields entered text is. I removed the restoration of this list for the experiment. And even removed the addition of these input fields after recovery. The result was the same. And what is most interesting, the additional_fields_block.removeAllViews() method does not work after the re-creation. Or rather, if I call it in onCreate or onStart or onResume . But if you create a button and hang a listener on it, and when you click to set this very removal of views, then when clicked, it deletes as it should.
I didn’t publish all the code, as there is a lot of it. But here are some parts.
onCreate:
var step = 1 var avatar_id : Int? = null var tempAdditionalFields = LinkedList<EditText>() var companies = LinkedList<Company>() val companiesAdapter = CompaniesShortListAdapter(companies) var dontSwitchFields = false override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_create_user) if (!restoreFromSavedInstance(savedInstanceState)){ GetCompaniesListTask().execute() } else dontSwitchFields = true switchUserInfoBtnsVis() switchFirmNameBtnsVis() switchChooseRoleBtnsVis() setListeners() switchStep(step) } Methods of saving and restoring (here I changed and commented out some lines for the experiment):
override fun onSaveInstanceState(outState: Bundle?) { outState?.let {bundle -> bundle.putInt("step", step) avatar_id?.let { bundle.putInt("avatar_id", it) } bundle.putSerializable("tempAdditionalFields", tempAdditionalFields) bundle.putSerializable("companies", companies) } super.onSaveInstanceState(outState) } fun restoreFromSavedInstance(savedInstanceState: Bundle?): Boolean { savedInstanceState?.let { bundle -> step = bundle.getInt("step") switchStep(step) avatar_id = bundle.getInt("avatar_id") // tempAdditionalFields.removeAll(tempAdditionalFields) // tempAdditionalFields.addAll(bundle.getSerializable("tempAdditionalFields") as Collection<EditText>) /* tempAdditionalFields.forEach { Log.e("TEST_EDIT", "edit: ${it.text}") }*/ additional_fields_block.removeAllViews() companies.removeAll(companies) companies.addAll(bundle.getSerializable("companies") as Collection<Company>) companiesAdapter.notifyDataSetChanged() return true } return false } I understand that the system itself restores these added views. But then at what stage? And I understand that in this case it would be possible to go the other way and just save the data entered in the fields, and then fill it out again. But I would like to get to the bottom of the truth, why I cannot delete the views added before the screen rotation ( EditText )