#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()
(это подход с дробовиком).