Как выделить полужирный текст с помощью библиотеки привязки данных Android

Довольно просто, я хочу сделать заголовок сообщения жирным в зависимости от того, читается ли текст или нет. Кажется, я не могу найти решение для этого.

Вот мой XML-код:

            <TextView
                android:text="@{message.title}"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignParentLeft="true"
                android:layout_alignParentStart="true"
                android:layout_alignParentTop="true"
                android:layout_marginBottom="5dp"
                android:layout_marginTop="5dp"
                android:layout_toLeftOf="@+id/timestamp"
                android:textSize="18sp"
                android:textStyle='@{message.isRead() ? "bold" : "normal"}'
                android:textColor='@{message.isRead() ? 0xff313131 : 0xff0662ab}' />

Смена цвета работает отлично, только жирный текст вызывает у меня некоторые проблемы.

Ошибка: не удалось выполнить задачу ': app: compileDebugJavaWithJavac'.

java.lang.RuntimeException: обнаружены ошибки привязки данных. **** / ошибка привязки данных **** msg: не удается найти установщик для атрибута android: textStyle с типом параметра java.lang.String в android.widget.TextView. файл: D: ...... xml loc: 39: 41 - 39:79 **** \ ошибка привязки данных ****


person Saif Bechan    schedule 03.06.2016    source источник
comment
Работает ли полужирный текст, если вы просто установите его статически, а не с привязкой данных?   -  person Marcin Koziński    schedule 03.06.2016
comment
Да, тогда это работает   -  person Saif Bechan    schedule 03.06.2016
comment
Я отредактирую ошибку   -  person Saif Bechan    schedule 03.06.2016


Ответы (7)


Легкий способ

public class TextViewBindingAdapter {
    @BindingAdapter("isBold")
    public static void setBold(TextView view, boolean isBold) {
        if (isBold) {
            view.setTypeface(null, Typeface.BOLD);
        } else {
            view.setTypeface(null, Typeface.NORMAL);
        }
    }
}

XML:

    <TextView
        android:id="@+id/text"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:isBold="@{item.bold}"/>
person tomrozb    schedule 06.03.2018
comment
Это правильное решение, принятый ответ устарел. - person k2col; 18.12.2018

В итоге я использовал следующий код, он реализует DataBinding.

public abstract class BindingAdapter {
    @android.databinding.BindingAdapter("android:typeface")
    public static void setTypeface(TextView v, String style) {
        switch (style) {
            case "bold":
                v.setTypeface(null, Typeface.BOLD);
                break;
            default:
                v.setTypeface(null, Typeface.NORMAL);
                break;
        }
    }
}

И XML

<TextView
    android:text="@{bericht.titel}"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentLeft="true"
    android:layout_alignParentStart="true"
    android:layout_alignParentTop="true"
    android:layout_marginBottom="5dp"
    android:layout_marginTop="5dp"
    android:layout_toLeftOf="@+id/timestamp"
    android:textSize="18sp"
    android:textColor='@{bericht.isGelezen() ? 0xff313131 : 0xff0662ab}'
    android:typeface='@{bericht.isGelezen() ? "normal" : "bold"}' />
person Saif Bechan    schedule 03.06.2016
comment
Это правильное решение, но в нем можно было бы внести небольшую поправку: связать с android: textStyle и использовать атрибут textStyle в вашем XML. - person Pepijn; 25.09.2016
comment
Я сохраняю этот статический метод в классе viewmodel public abstract static class BindingAdapter {@ android.databinding.BindingAdapter (android: typeface) public static void setTypeface (TextView v, String style) {switch (style) {case bold: v.setTypeface (null , Шрифт. BOLD); ломать; по умолчанию: v.setTypeface (null, Typeface.NORMAL); ломать; }}} и в xml android: typeface = '@ {bericht.isGelezen ()? нормальный: жирный} ' - person varotariya vajsi; 11.07.2018

Саиф Бечан прав в своем ответе, я сделал небольшое изменение, чтобы облегчить привязку данных из модели представления.

public abstract class BindingAdapter {
    @android.databinding.BindingAdapter("app:textStyle")
    public static void setTextStyle(TextView v, int style) {
        v.setTypeface(null, style);
    }
}

Затем вы добавляете пространство имен app в свой XML

<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
...
</layout>

Создайте привязку в модели представления

@Bindable
public int getValueFormat() {
    String message = getMyObject().getValue();
    if (message == MyObject.DEFAULT_VALUE)
        return Typeface.ITALIC;

    return Typeface.NORMAL;
}

Теперь вы можете привязать это напрямую

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    app:textStyle="@{viewModel.valueFormat}"
    android:text="@{viewModel.value}" />
person Kirk    schedule 10.04.2017

Вы можете сделать это без создания адаптера.

Импортируйте шрифт в ваш XML

<data>
    <import type="android.graphics.Typeface" />
...
</data>

Используйте атрибут android:typeface с Typeface.defaultFromStyle:

android:typeface="@{Typeface.defaultFromStyle(message.isRead() ? Typeface.BOLD : Typeface.NORMAL)}"
person Håkon Schia    schedule 19.10.2020

вам просто нужно импортировать Typeface в файл xml и сделать свою проверку следующим образом

    <variable
        name="vm"
        type="com.example.VM" />

    <import type="android.graphics.Typeface" />


        <TextView
            android:id="@+id/username"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textStyle="@{vm.isBold ? Typeface.BOLD : Typeface.NORMAL}"/>
person Andrew Emad    schedule 11.03.2020
comment
у меня не сработало. получение Не удается найти сеттер для ‹android.widget.TextView android: textStyle›, который принимает тип параметра 'int'. Вроде все-таки нужен кастомный переходник. - person Rainmaker; 14.05.2020

Итак, на этой неделе у меня была такая же проблема, я пытался использовать метод view.setTypeface(), но я хотел сохранить стиль шрифта в моем случае. Оказывается, жирный стиль сработал, когда я передал null в методе setTypeFace, но ... передача null может внести изменения в стиль шрифта (не смотрел на то же самое). Когда я попытался использовать тот же стиль шрифта и установить полужирный шрифт, это не сработало.

Чтобы добиться того, чего я хотел, поскольку мне не удалось использовать этот метод, я просто меняю стиль шрифта, когда требуется полужирный шрифт, см. Мой код:

@BindingAdapter("boldOrRegular")
@JvmStatic
    fun TextView.boldOrRegular(isBold: Boolean) {
        typeface = if (isBold) {
            ResourcesCompat.getFont(context, R.font.myfont_bold)
        } else {
            ResourcesCompat.getFont(context, R.font.myfont_regular)
        }
    }

Надеюсь, это кому-то поможет :)

person Paula Rosa    schedule 09.04.2021

Вам необходимо создать getMessageStyle в своем объекте сообщения:

public String getMessageStyle() {
    return isRead() ? "bold" : "normal";
}

затем используйте в своем коде, как показано ниже:

<TextView
    android:text="@{message.title}"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentLeft="true"
    android:layout_alignParentStart="true"
    android:layout_alignParentTop="true"
    android:layout_marginBottom="5dp"
    android:layout_marginTop="5dp"
    android:layout_toLeftOf="@+id/timestamp"
    android:textSize="18sp"
    android:textStyle="@{message.getMessageStyle()}"
    android:textColor="@{message.isRead() ? 0xff313131 : 0xff0662ab}" />
person Rohit Suthar    schedule 03.06.2016
comment
Я пробовал это, но это не сработало. Я нашел другой способ сделать это. Я отправлю свой ответ в ближайшее время. - person Saif Bechan; 03.06.2016