Ravi
Ravi

Reputation: 35549

set android:textAppearance with DataBinding

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

Answers (4)

Alexander Skvortsov
Alexander Skvortsov

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.

enter image description here

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"

As a Solution

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

Marcin Orlowski
Marcin Orlowski

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

Rohit Parmar
Rohit Parmar

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

Long Ranger
Long Ranger

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

Related Questions