Reputation: 35549
I am trying to set android:textAppearance
with use of DataBinding
, but it is not allowing me to use ?android:attr/textAppearanceLarge
with ternary operator.
android:textAppearance="@{position==1 ? ?android:attr/textAppearanceLarge : ?android:attr/textAppearanceMedium}"
It is showing me compile time error <expr> expected, got '?'
.
Does there any other way to use this with DataBinding?
Upvotes: 12
Views: 5355
Reputation: 2764
Looks like DataBinding treats android:textAppearance
in some special way (at least on Android Studio 3.2.1).
For example the following expression according to this should be fine, but it is not.
The following expression is being accepted by the compiler but it is doing nothing:
android:textAppearance="@{R.style.MyStyleTest}"
I have tried several options and only vanilla way worked for me:
android:textAppearance="@style/MyStyleTest"
I would suggest to use @BindingAdapter
and perform all the logic there.
For example if you would like to work with references to attributes (which looks like: ?attr/...
) use the following approach:
layout.xml
<TextView
...
bind:textAppearanceAttr="@{position==1 ? android.R.attr.textAppearanceLarge: android.R.attr.textAppearanceMedium}"
/>
sources.kt
@BindingAdapter(value = ["textAppearanceAttr"])
fun textAppearanceAttr(textView: TextView, @AttrRes attrRef: Int?) {
attrRef?.also {
val attrs = textView.context.obtainStyledAttributes(intArrayOf(attrRef))
val styleRes = attrs.getResourceId(0, -1)
attrs.recycle()
if (styleRes != -1) {
TextViewCompat.setTextAppearance(textView, styleRes)
}
}
}
or in case of style resource ids (@style/...
):
layout.xml
bind:textAppearanceStyle="@{position==1 ? R.style.MyStyleTest1: R.style.MyStyleTest2}"
sources.kt
@BindingAdapter(value = ["textAppearanceStyle"])
fun textAppearanceStyle(textView: TextView, @StyleRes style: Int?) {
style?.also { TextViewCompat.setTextAppearance(textView, it) }
}
Upvotes: 5
Reputation: 75629
You cannot use it directly, however here's trick I use in such cases. Create own styles using textAppearanceLarge
and textAppearanceMedium
as parents and then set these styles instead:
First create Foo
style:
<style name="Foo" parent="TextAppearance.AppCompat.Large">
... [whatever you need to set or override ] ...
</style>
and do the same for for FooMedium
. Then edit your layout file as shown below. Note you must import project's R
class in <data>
block first:
<data>
<import type="<your-package-id>.R"
</data>
Finally apply the appearance as you formerly wanted:
android:textAppearance="@{ position==1 ? R.style.Foo : R.style.FooMedium }"
Upvotes: 11
Reputation: 397
You should use textStyle instead of textAppearance,
Try to use code give below:
android:textStyle="@{position==1 ? @style/TextAppearance.Material.Large :@style/TextAppearance.Material.Medium}"
For more reference use below image
Upvotes: 0
Reputation: 6008
You can use android.R.attr package instead of the ?android:attr
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<data>
<import type="android.R.attr"/>
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="hello world"
android:textAppearance='@{age==1 ? android.R.attr.textAppearanceLarge : android.R.attr.textAppearanceMedium}'
tools:textAppearance="?android:textAppearanceLarge"
/>
</LinearLayout>
</layout>
Upvotes: 7