Использование ресурсов атрибутов (? Attr/) в привязке компоновки?
В настоящее время привязка данных в Android поддерживает следующие справочные ресурсы (согласно руководству по привязке данных): @array
, @color
, @int
, @dimen
, @string
..., который даст ссылочные значения в качестве аргументов в статическом методе @BindingAdapter
.
Например:
макет /web _view.xml
<WebView
app:htmlTextColor="@{@color/colorText}"
android:layout_width="match_parent"
android:layout_height="match_parent" />
Bindings.java
@BindingAdapter({"bind:htmlTextColor"})
public static void setHtml(WebView webView, int textColor) {
// binding logic
}
Но с темами и стилями, чаще всего я использую ресурс атрибута, например. ?android:attr/textColorPrimary
, чем a @color
. Для таких случаев, как бы выглядел синтаксис привязки "@{}"
? В настоящее время это то, как я заставляю его работать, но, может быть, есть лучший способ?
макет /web _view.xml
<WebView
app:htmlTextColor="@{android.R.attr.textColorPrimary}"
android:layout_width="match_parent"
android:layout_height="match_parent" />
Bindings.java
@BindingAdapter({"bind:htmlTextColor"})
public static void setHtml(WebView webView, int textColorAttr) {
// binding logic
}
Ответы
Ответ 1
Если @{android.R.attr.textColorPrimary}
разрешено значение android.R.attr.textColorPrimary
в Java, все, что вам нужно сделать, это разрешить это для цвета.
В этом есть немного настроек.
ContextUtils.java
Следующий метод разрешает поставку attr
темы context
и необязательный style
для цвета. Возвращается к цвету fallback
, если есть ошибка.
@ColorInt
public static int resolveColor(final Context context, @StyleRes final int style, @AttrRes final int attr, @ColorInt final int fallback) {
final TypedArray ta = obtainTypedArray(context, style, attr);
try {
return ta.getColor(0, fallback);
} finally {
ta.recycle()
}
}
@ColorInt
public static int resolveColor(final Context context, @AttrRes final int attr, @ColorInt final int fallback) {
return resolveColor(context, 0, attr, fallback);
}
Полезные методы, помогающие эффективно достичь вышеуказанной цели.
private static TypedArray obtainTypedArray(final Context context, @StyleRes final int style, @AttrRes final int attr): TypedArray {
final int[] tempArray = getTempArray();
tempArray[0] = attr;
return context.obtainStyledAttributes(style, tempArray);
}
private static final ThreadLocal<int[]> TEMP_ARRAY = new ThreadLocal<>();
private static final int[] getTempArray() {
int[] tempArray = TEMP_ARRAY.get();
if (tempArray == null) {
tempArray = int[1];
TEMP_ARRAY.set(tempArray);
}
return tempArray;
}
Более сложный код, доступный в my android-commons
library (эта часть написана в Kotlin, возьмите то, что вам нужно).
Bindings.java
Здесь, как его использовать:
@BindingAdapter({"bind:htmlTextColor"})
public static void setHtml(final WebView webView, @AttrRes final int textColorAttr) {
final Context context = webView.getContext();
final int textColor = ContextUtils.resolveColor(context, textColorAttr, Color.BLACK);
// binding logic
}
Ответ 2
Похоже, что темы в настоящее время не поддерживаются для использования в выражениях макета с привязкой данных, как объясняется @yigit в комментариях для вопроса здесь.
Ответ 3
Используйте BindingAdapter
BindingAdapter позволяет вам манипулировать и выполнять более сложную логику с вашими данными, прежде чем применять их к представлению. Чтобы использовать BindingAdapter, сначала создайте в своем коде статический метод, который привязан либо к стандартному атрибуту Android, либо к пользовательскому.
Я создаю пользовательский атрибут здесь с именем characterBackground:
@BindingAdapter({"characterBackground"})
public static void characterBackground(TextView textView, AdventureTimeCharacters character) {
textView.setBackgroundColor(ContextCompat.getColor(textView.getContext(), character.getColour()));
}
Затем вы можете использовать этот BindingAdapter в TextView:
app:characterBackground="@{character}"
Не забудьте добавить пространство имен приложения! Android Studio может добавить это для вас. Просто введите appNs, и он будет автоматически заполнен.
Это решение работает, но слишком сложно. И вы сказали, что привязка данных легко..