Когда использовать viewDataBinding.invalidateAll()

#android #data-binding #android-databinding #android-jetpack #android-navigation

#Android #привязка данных #android-привязка к данным #android-реактивный ранец #android-навигация

Вопрос:

Я пытался понять, когда binding.invalidateAll() необходимо обновить пользовательский интерфейс при изменении данных.

У меня есть 2 примера, в которых я изменяю данные, в одном из них данные пользовательского интерфейса изменяются автоматически, а в другом мне нужно использовать invalidateAll() , чтобы увидеть изменения

Прежде всего, ниже приведен XML TextView -файл, на котором я тестирую:

         ...
 
        <TextView
            android:id="@ id/name_text"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="@{mainActivity.myName.name}" />
 

Первый пример

В первом примере, если я изменяю данные внутри onCreate() или onResume() данные изменяются напрямую без необходимости invalidateAll() , пожалуйста, найдите код ниже:

     private lateinit var binding: ActivityMainBinding
    var myName = MyName(name = "Test")

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

        binding = DataBindingUtil.setContentView(this, R.layout.activity_main)
        binding.mainActivity = this;

        myName.name = "Data is visible directly"
    }
 

Здесь, как только пользовательский интерфейс отображается для пользователя, я вижу, что текст TextView напрямую устанавливается как «Данные видны напрямую» без необходимости вызова binding.invalidateAll()

Второй пример

Во втором примере я изменяю текст только при нажатии кнопки, как в приведенном ниже коде:

   ...

  fun onButtonClickedChangeData(view:View){
        myName.name = "Data is visible only after invalidateAll is called"
        binding.invalidateAll() // without it the text won't change
    }

 

Во втором примере я должен использовать binding.invalidateAll() для изменения текста TextView, если я не использую invalidateAll() текст, он не изменится.

Мое первое предположение (которое кажется неправильным)

Сначала я подумал, что, возможно binding.invalidateAll() , это необходимо, когда мы изменяем данные, пока действие уже запущено, и пользовательский интерфейс уже виден пользователю, и это invalidateAll() не понадобится, если данные изменятся до того, как пользовательский интерфейс будет еще отображен пользователю (учитывая, что пользовательский интерфейс виден только пользователю в onResumue() соответствии с мои знания).

Но когда я попытался обновить данные внутри onResumue() , данные также изменились напрямую, без необходимости binding.invalidateAll()

Комментарии:

1. Привет @Юсеф Гамаль, Ты не можешь просто использовать executePendingBindings() вместо invalidateAll() ? developer.android.com/reference/android/databinding /…

2. Привет @nuhkoca Спасибо, что упомянули executePendingBindings() , я не использовал его раньше, но я попробую. Но все же, честно говоря, интересно узнать, почему иногда invalidateAll() это необходимо, а в других случаях это не для обновления пользовательского интерфейса

3. 1 — Привязка данных — это не волшебство — она генерирует код, который вы можете сами устанавливать точки останова в трассировке, когда происходит привязка. 2. если вы создаете свои переменные, которые вы связываете (например, «имя») LiveData или Observable , тогда вам не нужно invalidateAll() (это подход с дробовиком).