Как указать цвет в ColorStateList?

Я пишу очень простой код, но столкнулся со странной проблемой. Я использую ColorStateList, чтобы подкрасить свой AppCompatImageButton. Вот код:

В макете:

<android.support.v7.widget.AppCompatImageButton
    android:layout_width = "48dp"
    android:layout_height = "48dp"
    app:srcCompat = "@drawable/ic_my_image"
    app:tint = "@color/my_image_tint_color"
    app:tintMode = "src_in"
    android:scaleType = "fitXY"/>

my_image_tint_color.xml:

<?xml version = "1.0" encoding = "utf-8"?>
<selector xmlns:android = "http://schemas.android.com/apk/res/android">
    <item android:color = "@color/colorGray" android:state_enabled = "false" />
    <item android:color = "@color/colorAccent" />
</selector>

Этот код работает правильно, и он подкрашивает мою кнопку изображения colorGray, если она отключена, в то время как по умолчанию она окрашена colorAccent.

Теперь я хочу изменить изображение кнопки на изображение с несколькими цветами. Поэтому я решил подкрасить кнопку colorGray, если она отключена, сохраняя исходные цвета изображения, если она не отключена. Но теперь я застрял. Есть ли что-то, что определяет Нет цвета в Android ColorStateList? Потому что мне нужно определить цвет для моего состояния по умолчанию в ColorStateList. Если я ничего не укажу для состояния по умолчанию, кнопка не будет отображаться (она кажется прозрачной по умолчанию, а кнопка будет окрашена прозрачным цветом). Я пытался указать @null как цвет в списке цветов, но это тоже не сработало.

Я знаю, что могу сделать это в коде, но предпочитаю делать это в XML. Есть ли способ подкрасить кнопку серым цветом, если она отключена, сохраняя при этом исходные цвета, если не в XML?

1
0
766
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Добавление 00 в начале сделает его прозрачным на 100%, а добавление FF сделает его на 100% сплошным. Предположим, ваш любимый цвет — красный #FF0000.

Итак, 100% прозрачный цвет: #00ff0000 и 100% сплошной цвет: #ffff0000

Любое значение от 00 до ff можно использовать для настройки прозрачности.

Поэтому добавьте прозрачные цвета в colors.xml, а затем получите доступ к ним из drawable

цвета.xml

<?xml version = "1.0" encoding = "utf-8"?>
<resources>
    <color name = "trasnparent">#00ff0000</color>
</resources>

my_image_tint_color.xml

<?xml version = "1.0" encoding = "utf-8"?>
<selector xmlns:android = "http://schemas.android.com/apk/res/android">
    <item android:color = "@color/colorGray" android:state_enabled = "false" />
    <item android:color = "@color/colorAccent" 
    <item android:color = "@color/transparent" android:state_something = "true"/>
</selector>

пожалуйста, дайте мне знать, если это поможет вам и дать голос. Спасибо

Это не работает. Если я подкрашу свое изображение цветом transparent, изображение станет прозрачным, пока я хочу видеть изображение. Что я хочу, так это видеть изображение (как-то без оттенка) по умолчанию, а тонировать серый для отключенного состояния.

Afshin 08.04.2019 09:00

Вы можете добавить прозрачный цвет, например #00ff0000.

Ответ принят как подходящий

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

Для моей проблемы мне нужно использовать режим оттенка multiply, который может решить мою проблему. Вот как вы его используете:

В макете:

<android.support.v7.widget.AppCompatImageButton
    android:layout_width = "48dp"
    android:layout_height = "48dp"
    app:srcCompat = "@drawable/ic_my_image"
    app:tint = "@color/my_image_tint_color"
    app:tintMode = "multiply"
    android:scaleType = "fitXY"/>

my_image_tint_color.xml:

<?xml version = "1.0" encoding = "utf-8"?>
<selector xmlns:android = "http://schemas.android.com/apk/res/android">
    <item android:color = "#20909090" android:state_enabled = "false" />
    <item android:color = "#FFFFFFFF" />
</selector>

С помощью этого кода вы видите свою кнопку полноцветной, когда она включена. Но если вы отключите кнопку, она станет серой.

Как это работает:

Режим оттенка multiply определяется следующим уравнением:

Multiplies the color and alpha channels of the drawable with those of the tint. [Sa * Da, Sc * Dc]

Этот режим оттенка может только уменьшать значения цвета, поэтому его можно использовать только для затемнения ваших цветов. Просто чтобы понять следующее, помните, что вам нужно масштабировать значения цвета 0x00-0xFF в 0.0f-1.0f, поэтому 0x00 будет равно 0.0f, а 0xFF будет равно 1.0f. В общем, это означает, что вам нужно работать со значениями с плавающей запятой в качестве номера цвета, где:

floating_point_color = byte_color / 255

Кроме того, помните, что в 4-байтовом цветовом формате, таком как #AABBCCDD, AA, это альфа, а другие байты показывают красный, зеленый и синий.

Хорошо, как вы используете эту функцию для моей проблемы?

  1. Я хочу сохранить цвета изображения, когда кнопка включена. Поэтому мне нужно сохранить альфа-канал изображения и цвета как есть. Затем мне нужно использовать цвет #FFFFFFFF для включения цвета. В этом случае цвет и альфа каждого пикселя моего исходного изображения будут умножены на 1,0f (поскольку байт равен 0xFF), поэтому исходное изображение не изменится.
  2. Чтобы мое изображение отображалось в оттенках серого в отключенном режиме, я использовал значение #20909090. Сначала я использовал 90 для красного, зеленого и синего цветов. Потому что я хочу затемнить эти цвета, но все в одном масштабе. Это затемняет все цвета в одной шкале, поэтому ваш цвет не будет чем-то ненормальным. С этой шкалой белый цвет становится светло-серым (0x909090), а черный остается черным. Но затем я использовал 20 для альфа-канала цвета, чтобы сделать полученные цвета более прозрачными. Таким образом, если фон вашего изображения белый, вы увидите отличное тонированное изображение в оттенках серого по сравнению с исходным изображением.

Это решило мою проблему, но я считаю это действительно полезным примером свойства tintMode. Я всем понравится этот небольшой учебник.

Вы должны были попробовать режим SRC_ATOP, я думаю, это сделало бы то, что вы ожидаете.

В макете:

    <android.support.v7.widget.AppCompatImageButton
        android:layout_width = "48dp"
        android:layout_height = "48dp"
        app:srcCompat = "@drawable/ic_my_image"
        app:tint = "@color/my_image_tint_color"
        app:tintMode = "src_atop"
        android:scaleType = "fitXY"/>

my_image_tint_color.xml:

    <?xml version = "1.0" encoding = "utf-8"?>
    <selector xmlns:android = "http://schemas.android.com/apk/res/android">
        <item android:color = "@color/colorGray" android:state_enabled = "false" />
        <item android:color = "@color/transparent" />
    </selector>

это работает, в основном использует tintMode так же, как ответ OP, однако это проще, поскольку мы можем просто использовать исходный цвет, не играя с умножениями. Спасибо!

Bruce 17.12.2021 02:39

Другие вопросы по теме