Я пишу очень простой код, но столкнулся со странной проблемой. Я использую 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?
Добавление 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>
пожалуйста, дайте мне знать, если это поможет вам и дать голос. Спасибо
Вы можете добавить прозрачный цвет, например #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
, это альфа, а другие байты показывают красный, зеленый и синий.
Хорошо, как вы используете эту функцию для моей проблемы?
#FFFFFFFF
для включения цвета. В этом случае цвет и альфа каждого пикселя моего исходного изображения будут умножены на 1,0f (поскольку байт равен 0xFF), поэтому исходное изображение не изменится.#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, однако это проще, поскольку мы можем просто использовать исходный цвет, не играя с умножениями. Спасибо!
Это не работает. Если я подкрашу свое изображение цветом
transparent
, изображение станет прозрачным, пока я хочу видеть изображение. Что я хочу, так это видеть изображение (как-то без оттенка) по умолчанию, а тонировать серый для отключенного состояния.