Ответ 1
Я не могу установить перечисление по значению, но только по имени
Это не совсем верно. Вы не сможете установить значение с помощью DataBinding даже по имени, дело в том, что значение атрибута, определенного в xml, передается в View
через конструктор. В View
может быть как атрибут, так и сеттер, но это необязательно. Например, вы задали значение для android:text
TextView
, для этого значения установлено значение com.android.internal.R.styleable.TextView_text
который затем извлекается из AttributeSet
в конструкторе. Если вы используете DataBinding, вызывается setText()
, но это две совершенно разные вещи, эта функция одна и та же, но они не связаны в коде.
Учитывая, что вы не можете изменять MyInnerView
и что нет setter, вы можете вызвать myAttr
, ваш единственный вариант - передать его через конструктор. DataBinding просто не представляется возможным, даже с BinderAdapter вы не смогли бы установить значение в AttributeSet
, поскольку View
уже инициализируется в этой точке.
Вариант 1 - темы
Определить новый атрибут
<attr name="MyInnerViewAttrValue" format="integer" />
Затем разрешите этот атрибут со стилем, например, вы могли бы
<style name="AppTheme.Foo">
<item name="MyInnerViewAttrValue">0</item>
</style>
<style name="AppTheme.Bar">
<item name="MyInnerViewAttrValue">1</item>
</style>
Установите его в макет xml
<com.example.MyInnerView
...
app:myAttr="?attr/MyInnerViewAttrValue" />
А затем вызовите setTheme(int)
в Activity
перед созданием представлений.
Вариант 2 - пользовательский BindingAdapter
Если вы хотите установить значение DataBinding (потому что у вас был сеттер или потому, что вы хотели взломать MyInnerView
с отражением), вам нужно будет создать собственный BindingAdapter, например
@BindingAdapter("myAttrValue")
public static void setMyAttr(MyInnerView myInnerView, int value) {
switch (value) {
case 0:
myInnerView.foo();
break;
default:
myInnerView.bar();
}
}
Затем в макете xml
<com.example.lelloman.dummy.MyInnerView
...
myAttrValue="@{model.attr}" />
И дайте значение int
из вашей ViewModel
public class MyInnerViewModel {
public int getAttr() {
return 1234;
}
}