Сохраните EditText с поворотом экрана, используя библиотеку привязки данных

У меня есть два класса AdminPinActivity.kt и AdminPinActivityPresenter.kt

AdminPinActivity.kt:

  class AdminPinActivity : InjectableAppCompatActivity() {
  @Inject
  lateinit var adminPinActivityPresenter: AdminPinActivityPresenter
  private var input_Pin: String = ""
  private var input_Confirm_Pin: String = ""

  companion object {
    fun createAdminPinActivityIntent(context: Context, profileId: Int, colorRgb: Int): Intent {
      val intent = Intent(context, AdminPinActivity::class.java)
      intent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY)
      intent.putExtra(KEY_ADMIN_PIN_PROFILE_ID, profileId)
      intent.putExtra(KEY_ADMIN_PIN_COLOR_RGB, colorRgb)
      return intent
    }
  }

  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    activityComponent.inject(this)

    adminPinActivityPresenter.handleOnCreate(savedInstanceState)
  }

  override fun onSaveInstanceState(outState: Bundle) {
    adminPinActivityPresenter.handleOnSavedInstanceState(outState)
    super.onSaveInstanceState(outState)
  }

  override fun onSupportNavigateUp(): Boolean {
    finish()
    return false
  }
}

AdminPinActivityPresenter.kt:

    /** The presenter for [AdminPinActivity]. */
@ActivityScope
class AdminPinActivityPresenter @Inject constructor(
  private val context: Context,
  private val activity: AppCompatActivity,
  private val profileManagementController: ProfileManagementController,
  private val viewModelProvider: ViewModelProvider<AdminPinViewModel>
) {
  private val adminViewModel by lazy {
    getAdminPinViewModel()
  }

  private var input_Pin: String = ""
  private var input_Confirm_Pin: String = ""

  /** Binds ViewModel and sets up text and button listeners. */
  fun handleOnCreate(savedInstanceState: Bundle?) {
    activity.title = activity.getString(R.string.add_profile_title)
    activity.supportActionBar?.setDisplayHomeAsUpEnabled(true)
    activity.supportActionBar?.setHomeAsUpIndicator(R.drawable.ic_close_white_24dp)

    val binding =
      DataBindingUtil.setContentView<AdminPinActivityBinding>(activity, R.layout.admin_pin_activity)

    binding.apply {
      lifecycleOwner = activity
      viewModel = adminViewModel
    }               

    if (savedInstanceState != null) {

      if (savedInstanceState.getString("InputPin") != null) {
        Log.i("Input pin from savedInstanceState",savedInstanceState.getString("InputPin"))
        binding.inputPin.input.setText(savedInstanceState.getString("InputPin"))

      }
      if (savedInstanceState.getString("InputConfirmPin") != null) {
        binding.inputConfirmPin.input.setText(savedInstanceState.getString("InputConfirmPin"))
      }
      binding.executePendingBindings()
    }       

      binding.inputPin.addTextChangedListener(object :TextWatcher{
      override fun afterTextChanged(p0: Editable?) {}

      override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
      }
      override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
        input_Pin=p0.toString().trim()
      }
    })

    binding.inputConfirmPin.addTextChangedListener(object : TextWatcher {
      override fun afterTextChanged(p0: Editable?) {
        input_Confirm_Pin=p0.toString().trim()
      }

      override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
      }

      override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
      }
    })




  }

  fun handleOnSavedInstanceState(bundle: Bundle) {    
    bundle.putString("InputPin", input_Pin)
    Log.i("input_Pin",input_Pin)
    bundle.putString("InputConfirmPin", input_Confirm_Pin)    
  }


  private fun getAdminPinViewModel(): AdminPinViewModel {
    return viewModelProvider.getForActivity(activity, AdminPinViewModel::class.java)
  }
}

Log.i("Input pin from savedInstanceState",savedInstanceState.getString("InputPin")) и Log.i("input_Pin",input_Pin) регистрируются при каждой ротации. Это означает, что код работает нормально, но значения EditText не обновляются, т. е. binding.inputPin.input.setText(savedInstanceState.getString("InputPin")) и binding.inputConfirmPin.input.setText(savedInstanceState.getString("InputConfirmPin")) работают неправильно.

Когда я использую binding.inputPin.input.setText("Something") вне операторов if, то есть внутри handleOnCreateMethod, тогда он обновляет значение EditText с помощью «Something» один раз. Но при повороте экрана это тоже теряется.

Я надеюсь, вы понимаете вопрос.

Я искал везде почти два дня и не могу найти решение. Я не хочу использовать двустороннюю привязку данных.

admin_pin_activity.xml

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:app="http://schemas.android.com/apk/res-auto"
  xmlns:profile="http://schemas.android.com/tools">
  <data>
    <variable
      name="viewModel"
      type="org.oppia.app.profile.AdminPinViewModel" />
  </data>
  <ScrollView
    android:id="@+id/scrollViewAdminPin"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/addProfileBackground">
    <androidx.constraintlayout.widget.ConstraintLayout
      android:id="@+id/admin_auth_container"
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      android:background="@color/addProfileBackground">
      <TextView
        android:id="@+id/admin_pin_main_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/admin_pin_requirement_description"
        android:textColor="@color/oppiaPrimaryText"
        android:textSize="16sp"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        android:layout_marginTop="32dp"
        android:paddingStart="32dp"
        android:paddingEnd="32dp"/>
      <TextView
        android:id="@+id/admin_pin_warning_text"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/admin_pin_pin_description"
        android:textSize="16sp"
        android:textColor="@color/oppiaPrimaryText"
        app:layout_constraintTop_toBottomOf="@+id/admin_pin_main_text"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        android:layout_marginTop="16dp"
        android:paddingStart="32dp"
        android:paddingEnd="32dp"/>
      <org.oppia.app.profile.ProfileInputView
        android:id="@+id/input_pin"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="8dp"
        app:layout_constraintTop_toBottomOf="@+id/admin_pin_warning_text"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:label="@string/admin_pin_new_pin"
        app:isPasswordInput="true"
        app:inputLength="5"
        profile:error="@{viewModel.pinErrorMsg}"/>
      <org.oppia.app.profile.ProfileInputView
        android:id="@+id/input_confirm_pin"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_constraintTop_toBottomOf="@+id/input_pin"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:label="@string/admin_pin_new_confirm"
        app:isPasswordInput="true"
        app:inputLength="5"
        profile:error="@{viewModel.confirmPinErrorMsg}"/>
      <Button
        android:id="@+id/submit_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/admin_pin_submit"
        style="@style/StateButtonActive"
        app:layout_constraintTop_toBottomOf="@+id/input_confirm_pin"
        app:layout_constraintEnd_toEndOf="parent"
        android:layout_marginTop="20dp"
        android:layout_marginEnd="32dp"/>
    </androidx.constraintlayout.widget.ConstraintLayout>
  </ScrollView>
</layout>

profile_input_view.xml:

<?xml version="1.0" encoding="utf-8"?>
<layout>

  <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginStart="28dp"
    android:layout_marginTop="32dp"
    android:layout_marginEnd="28dp"
    android:descendantFocusability="beforeDescendants"
    android:focusableInTouchMode="true"
    android:orientation="vertical">

    <TextView
      android:id="@+id/label_text"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:layout_marginStart="4dp"
      android:fontFamily="sans-serif"
      android:textAllCaps="true"
      android:textColor="@color/oppiaPrimaryText"
      android:textSize="12sp" />

    <EditText
      android:id="@+id/input"
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      android:layout_marginTop="4dp"
      android:background="@drawable/add_profile_edit_text_background"
      android:fontFamily="sans-serif"
      android:padding="8dp"
      android:textColor="@color/oppiaPrimaryText"
      android:textSize="14sp"
      android:textStyle="italic" />

    <TextView
      android:id="@+id/error_text"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:textColor="@color/red" />
  </LinearLayout>
</layout>

person NullByte08    schedule 13.03.2020    source источник
comment
В onSaveInstanceState() вызовите super перед handleOnSavedInstanceState(). – Четикамп 12 минут назад   -  person Cheticamp    schedule 13.03.2020
comment
Кроме того, обязательно вызовите super для восстановления состояния экземпляра перед изменением текстовых значений редактирования. Я думаю, что фреймворк перезаписывает ваши изменения. Изменяя порядок, вы вместо этого перезаписываете изменения фреймворка, что вам и нужно.   -  person Cheticamp    schedule 13.03.2020
comment
Я вызвал метод onrestoreinstancestate, но по какой-то причине edittext сохраняется только для ввода в inputconfirmpin edittext, а не в inputpin edittext.   -  person NullByte08    schedule 13.03.2020
comment
Я думаю, что это правильный путь. Вам вообще не нужно сохранять/восстанавливать EditTexts, так как Android сделает это за вас. (Не все представления, но определенно EditText.) Если вам нужно сохранить/восстановить EditText, продолжайте смотреть на последовательность и используйте отладчик, чтобы получить дескриптор что здесь происходит. Если это не сработает, возможно, вам придется подождать, пока кто-то не даст полный ответ.   -  person Cheticamp    schedule 13.03.2020
comment
Я написал ответ, пожалуйста, проверьте.   -  person NullByte08    schedule 13.03.2020
comment
Android не сохраняет текст редактирования самостоятельно. Я тоже пробовал :/   -  person NullByte08    schedule 13.03.2020
comment
ХОРОШО. Не уверен что происходит. Ваш ответ на самом деле не ответ. Я бы удалил это. (В любом случае модератор может удалить его.) Я думаю, что у вас больше шансов получить ответ, если ответа нет.   -  person Cheticamp    schedule 13.03.2020
comment
Вы, кажется, не используете двустороннюю привязку. Можете ли вы показать макет XML и содержащийся в нем код привязки? Вероятно, когда вы вызываете executePendingBindings(), привязка перезапишет текст, который вы установили вручную, независимо от того, какой источник вы используете.   -  person BladeCoder    schedule 18.03.2020
comment
Я тоже пробовал свой код без использования executePendingBindings(). Он показывает тот же результат. А также я не использую двухстороннюю привязку. На самом деле у меня есть пользовательский вид, поэтому нет такого атрибута, как android:text, который я мог бы использовать для одной из конечных точек двухсторонней привязки.   -  person NullByte08    schedule 18.03.2020
comment
Я попытался добавить атрибут (в attrs), но мой пользовательский вид не отображался, и я пропустил идею двусторонней привязки.   -  person NullByte08    schedule 18.03.2020
comment
@Cheticamp Думаю, я понял это. Я использовал customView с именем ProfileInputView. Внутри него есть EditText. Это означает, что каждый экземпляр этого ProfileInputVie имеет одинаковый идентификатор для этого EditText. Это означает, что каждый экземпляр будет содержать одно и то же значение для текстового поля...... Есть ли способ дать уникальный идентификатор EditText для каждого экземпляра ProfileInputView .   -  person NullByte08    schedule 18.03.2020
comment
@BladeCoder Не могли бы вы тоже взглянуть   -  person NullByte08    schedule 18.03.2020
comment
Предпочтительно, чтобы представления восстанавливали свое собственное состояние, а не делали это вручную. Если у вас есть пользовательское представление, содержащее другие представления, вам необходимо реализовать собственный код для saveInstanceState и restoreInstanceState в пользовательском представлении и отключить автоматическое восстановление состояния для внутренних представлений с помощью android:saveEnabled="false".   -  person BladeCoder    schedule 18.03.2020
comment
Я согласен с @BladeCoder, и это будет лучший подход. Вы также можете попробовать присвоить уникальный идентификатор полю EditText в своем пользовательском представлении, используя View.generateId(). Вы должны были бы разработать детали.   -  person Cheticamp    schedule 19.03.2020
comment
@BladeCoder Большое спасибо, чувак. Вы решили это. Cheticamp тоже благодарит вас за помощь.   -  person NullByte08    schedule 19.03.2020