TextView оттенок на AppCompat

Я сделал несколько флажков и переключателей с текстовыми изображениями, но они не получают тонированное пред-Lollipop.

Мое текстовое изображение расширяется AppCompatCheckedTextView, оформляется как:

<style name="CheckBoxStyle" parent="android:Widget.TextView">
    <item name="android:textAppearance">?android:attr/textAppearance</item>
    <item name="android:drawableRight">?android:attr/listChoiceIndicatorMultiple</item>
    <item name="android:drawableEnd">?android:attr/listChoiceIndicatorMultiple</item>
    <item name="android:clickable">true</item>
    <item name="android:background">?attr/selectableItemBackground</item>
    <item name="android:gravity">center_vertical</item>
    <item name="android:paddingTop">8dp</item>
    <item name="android:paddingBottom">8dp</item>
</style>

и у меня есть мой акцент, определенный в моей теме:

<style name="AppTheme.Platform.NoActionBar" parent="Theme.AppCompat.NoActionBar">
    <item name="android:selectableItemBackground">@drawable/press_overlay_dark</item>
    <item name="android:borderlessButtonStyle">@style/BorderlessButton</item>

    <item name="android:colorAccent">@color/color_accent</item>
    <item name="colorAccent">@color/color_accent</item>
</style>

Я строю против v21, с минимумом v16 и с помощью AppCompat v7-22.1.1. Мои действия расширяют AppCompatActivity

Genymotion 4.1.1Nexus 5 5.1.1

Ответ 1

Глядя на источник для AppCompatCheckedTextView, я, наконец, понял это. Показывает только checkMark. Поскольку он происходит от CheckedTextView, который происходит от TextView, drawableRight только тонируется на леденец. Рассматривая источник AppCompatTextView, он обеспечивает только обратную совместимость textAllCaps. Итак, AFAIK, нет встроенного способа tint drawableRight и тому подобного pre-lollipop. Если вам нужно более настраиваемое решение, вам может потребоваться разместить ваши чертежи в макете.

Обновленный стиль:

<style name="CheckBoxStyle" parent="android:Widget.TextView">
    <item name="android:textAppearance">@style/TextAppearance.AppCompat</item>
    <item name="android:checkMark">?android:attr/listChoiceIndicatorSingle</item>
    <item name="android:clickable">true</item>
    <item name="android:background">?attr/selectableItemBackground</item>
    <item name="android:gravity">center_vertical</item>
    <item name="android:paddingTop">8dp</item>
    <item name="android:paddingBottom">8dp</item>
</style>

Ответ 2

Для уровня API 23> = android:drawableTint="@color/colorPrimary"

Для уровня API & lt; Уровень API 23 :

JAVA

private void setTextViewDrawableColor(@RecentlyNonNull TextView textView,@ColorRes int color) {
        for (Drawable drawable : textView.getCompoundDrawables()) {
            if (drawable != null) {
                drawable.setColorFilter(new PorterDuffColorFilter(getColor(color), PorterDuff.Mode.SRC_IN));
            }
        }
    }

ИСПОЛЬЗОВАНИЕ: setTextViewDrawableColor(txtMyDemoText,R.color.colorPrimary)


Функция расширения Kotlin

  fun TextView.setDrawableColor(@ColorRes color: Int) {
          compoundDrawables.filterNotNull().forEach {
              it.colorFilter = PorterDuffColorFilter(getColor(context, color), PorterDuff.Mode.SRC_IN)
        }
   }

ИСПОЛЬЗОВАНИЕ: txtMyDemoText.setDrawableColor(R.color.colorPrimary)

Ответ 3

Не прямой ответ на решение. Однако, если вы используете привязку данных и хотите добавить оттенок для рисования. Посмотрите на следующий пример: протестировано на последних версиях, но также должно работать на Api <= 21

  @JvmStatic
    @BindingAdapter(value = ["app:drawableStart", "app:drawableStartTint"], requireAll = true)
    fun setDrawableStartTint(textView: TextView, @DrawableRes drawable: Drawable, @ColorInt color: Int) {
        val mutatedDrawable = drawable.mutate()
        mutatedDrawable.setColorFilter(color, PorterDuff.Mode.MULTIPLY)
        textView.setCompoundDrawablesWithIntrinsicBounds(mutatedDrawable, null, null, null)
    }

Использование:

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Hello World"
    app:drawableStart="@{@drawable/ic_demo}"
    app:drawableStartTint="@{@color/color_demo_tint}"
 />

Ответ 4

Для API 23 и выше, просто установите его в свой макет: android:drawableTint="@color/custom_color"

Если вам нужна обратная совместимость, вам нужно будет установить ее программно. В Kotlin вы можете создать функцию расширения, например:

fun TextView.setDrawableColor(@ColorRes color: Int) {
    compoundDrawables.filterNotNull().forEach {
        it.colorFilter = PorterDuffColorFilter(getColor(context, color), PorterDuff.Mode.SRC_IN)
    }
}

И используйте его как: textView.setDrawableColor(R.color.custom_color)

Обратите внимание, что filterNotNull() здесь очень важен, поскольку список элементов рисования, вероятно, будет иметь некоторые нулевые значения (для всех элементов рисования TextView, которые не были установлены).

Ответ 5

Вот обратный совместимый TextView.

Использование:

<com.github.mrezanasirloo.TextViewCompatTint
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:drawableStart="@drawable/ic_comment_black_14dp"
    app:drawableTint="@color/colorPrimary"
    tools:text="28"
    />

суть

Ответ 6

У меня проблема с оттенком. AppCompatTextView не имеет эффекта оттенка при работе на SDK ниже 21. Мое решение устанавливает цвет оттенка через java. Пример ниже работает.

XML

    <android.support.v7.widget.AppCompatTextView
    android:layout_width="50dp"
    android:layout_height="20dp"
    android:id="@+id/tvInfor2"
    android:background="@drawable/btn_style_black_border"
    android:gravity="center"
    android:backgroundTint="@color/colorPrimary"/>

Java

    int currentapiVersion = android.os.Build.VERSION.SDK_INT;
    if (currentapiVersion <= 21){
        tvInfor2.setSupportBackgroundTintList(getResources().getColorStateList(R.color.colorPrimary));
    }

Ответ 7

Подчеркивание виджета в AppCompat работает, перехватывая любую инфляцию макета и вставляя специальную версию виджета на свое место. Если у вас есть собственная пользовательская версия виджета, которая в вашем случае является checktextview, тонирование не работает

Из блога разработчиков под цветом виджета

http://android-developers.blogspot.com/2014/10/appcompat-v21-material-design-for-pre.html

При работе на устройствах с Android 5.0 все виджеты окрашены с использованием атрибутов цветовой темы, о которых мы только что говорили. Есть две основные функции, которые позволяют это на Lollipop: рисовать тонирование и ссылаться на атрибуты темы (формы? Attr/foo) в drawables.

AppCompat обеспечивает аналогичное поведение в более ранних версиях Android для подмножества виджета пользовательского интерфейса:

Все, что предусмотрено панелью инструментов AppCompats (режимы действия и т.д.)

EditText

Вертушка

CheckBox

RadioButton

Переключатель (используйте новый файл android.support.v7.widget.SwitchCompat)

CheckedTextView

Вам не нужно делать что-либо особенное, чтобы сделать эти работы, просто используйте эти элементы управления в своих макетах, как обычно, и AppCompat сделает все остальное (с некоторыми оговорками, см. раздел "Вопросы и ответы" ниже).

Ответ 8

В котлин:

fun TextView.setDrawableTintColor(colorRes: Int) {
  for (drawable in this.compoundDrawablesRelative) {
    drawable?.colorFilter = PorterDuffColorFilter(getColor(context, colorRes), PorterDuff.Mode.SRC_IN)
  }
}

Использование:

myTextView.setDrawableTintColor(R.color.colorPrimary)