AppCompat 上的 TextView 色调
TextView tint on 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
AppCompat 中的小部件着色通过拦截任何布局 inflation 并在其 place.if 中插入小部件的特殊着色感知版本来工作 place.if 您有自己的小部件自定义版本,其中你的情况是 checkedtextview ,着色不起作用
来自小部件着色下的开发者博客
http://android-developers.blogspot.com/2014/10/appcompat-v21-material-design-for-pre.html
当 运行 在具有 Android 5.0 的设备上时,所有小部件都使用我们刚才谈到的颜色主题属性进行着色。在 Lollipop 上有两个主要功能允许这样做:drawable 着色和在 drawables 中引用主题属性(形式为 ?attr/foo)。
AppCompat 在 Android 的早期版本中为 UI 个小部件的子集提供了类似的行为:
AppCompat 工具栏提供的一切(操作模式等)
编辑文本
旋转器
复选框
单选按钮
切换(使用新的android.support.v7.widget.SwitchCompat)
CheckedTextView
您不需要做任何特别的事情来使这些工作正常,只需像往常一样在您的布局中使用这些控件,AppCompat 将完成其余的工作(有一些注意事项;请参阅下面的常见问题解答)。
查看 AppCompatCheckedTextView
的来源,我终于明白了。 它只为 checkMark
着色。由于它源自 CheckedTextView
,而后者源自 TextView
,因此 drawableRight
仅在棒棒糖上着色。查看 AppCompatTextView
的源代码,它只提供向后兼容的 textAllCaps
。 所以 AFAIK,没有内置的方法来为 drawableRight
和类似的棒棒糖之前的颜色着色。 如果你想要一个更可定制的解决方案,你可能需要把你的 drawables 放在布局。
更新后的样式:
<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>
我有一个色调问题。 AppCompatTextView 在低于 21 的 SDK 上 运行 时没有色调效果。我的解决方案是通过 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));
}
对于Api 23级>= android:drawableTint="@color/colorPrimary"
对于Api级别:
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)
这是一个向后兼容的 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"
/>
不是对解决方案的直接回答。但是,如果您正在使用数据绑定并想要添加可绘制色调。查看以下示例:已在最新版本上测试,但也应该适用于 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}"
/>
对于 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 可绘制对象)。
在kotlin中:
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)
简化最上面的答案,它将是 Kotlin 中的扩展(但我没有检查):
fun TextView.setDrawableColor(@ColorRes color: Int) {
val colorFilter = PorterDuffColorFilter(getColor(context, color), PorterDuff.Mode.SRC_IN)
compoundDrawables.filterNotNull().forEach {
it.colorFilter = colorFilter
}
}
在所有对我不起作用的解决方案中,我创建了以下解决方案:
JAVA: 兼容 Api < 23
private void setTextViewDrawableColor(@RecentlyNonNull TextView textView,@ColorRes int color) {
for (Drawable drawable : textView.getCompoundDrawablesRelative()) {
if (drawable != null) {
drawable.setColorFilter(new PorterDuffColorFilter(ContextCompat.getColor(textView.getContext(),color), PorterDuff.Mode.SRC_IN));
}
}
}
使用
setTextViewDrawableColor(textView1,R.color.AccentColor)
KOTLIN
private fun setTextViewDrawableColor(@NonNull textView: TextView, @ColorRes color: Int) {
for (drawable in textView.compoundDrawablesRelative) {
if (drawable != null) {
drawable.colorFilter = PorterDuffColorFilter(ContextCompat.getColor(textView.context, color), PorterDuff.Mode.SRC_IN)
}
}
}
使用
setTextViewDrawableColor(textView1,R.color.AccentColor)
KOTLIN 扩展
fun TextView.setDrawableColor(@ColorRes color: Int) {
compoundDrawablesRelative.filterNotNull().forEach {
it.colorFilter = PorterDuffColorFilter(ContextCompat.getColor(this.context, color), PorterDuff.Mode.SRC_IN)
}
}
使用
textView1.setDrawableColor(R.color.colorAccent)
只有 XML API => 23
android:backgroundTintMode="src_in"
android:drawableTint="FF0000"
我用文本视图制作了一些复选框和单选按钮,但它们在 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
AppCompat 中的小部件着色通过拦截任何布局 inflation 并在其 place.if 中插入小部件的特殊着色感知版本来工作 place.if 您有自己的小部件自定义版本,其中你的情况是 checkedtextview ,着色不起作用
来自小部件着色下的开发者博客
http://android-developers.blogspot.com/2014/10/appcompat-v21-material-design-for-pre.html
当 运行 在具有 Android 5.0 的设备上时,所有小部件都使用我们刚才谈到的颜色主题属性进行着色。在 Lollipop 上有两个主要功能允许这样做:drawable 着色和在 drawables 中引用主题属性(形式为 ?attr/foo)。
AppCompat 在 Android 的早期版本中为 UI 个小部件的子集提供了类似的行为:
AppCompat 工具栏提供的一切(操作模式等)
编辑文本
旋转器
复选框
单选按钮
切换(使用新的android.support.v7.widget.SwitchCompat)
CheckedTextView
您不需要做任何特别的事情来使这些工作正常,只需像往常一样在您的布局中使用这些控件,AppCompat 将完成其余的工作(有一些注意事项;请参阅下面的常见问题解答)。
查看 AppCompatCheckedTextView
的来源,我终于明白了。 它只为 checkMark
着色。由于它源自 CheckedTextView
,而后者源自 TextView
,因此 drawableRight
仅在棒棒糖上着色。查看 AppCompatTextView
的源代码,它只提供向后兼容的 textAllCaps
。 所以 AFAIK,没有内置的方法来为 drawableRight
和类似的棒棒糖之前的颜色着色。 如果你想要一个更可定制的解决方案,你可能需要把你的 drawables 放在布局。
更新后的样式:
<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>
我有一个色调问题。 AppCompatTextView 在低于 21 的 SDK 上 运行 时没有色调效果。我的解决方案是通过 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));
}
对于Api 23级>= android:drawableTint="@color/colorPrimary"
对于Api级别
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)
这是一个向后兼容的 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"
/>
不是对解决方案的直接回答。但是,如果您正在使用数据绑定并想要添加可绘制色调。查看以下示例:已在最新版本上测试,但也应该适用于 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}"
/>
对于 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 可绘制对象)。
在kotlin中:
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)
简化最上面的答案,它将是 Kotlin 中的扩展(但我没有检查):
fun TextView.setDrawableColor(@ColorRes color: Int) {
val colorFilter = PorterDuffColorFilter(getColor(context, color), PorterDuff.Mode.SRC_IN)
compoundDrawables.filterNotNull().forEach {
it.colorFilter = colorFilter
}
}
在所有对我不起作用的解决方案中,我创建了以下解决方案:
JAVA: 兼容 Api < 23
private void setTextViewDrawableColor(@RecentlyNonNull TextView textView,@ColorRes int color) {
for (Drawable drawable : textView.getCompoundDrawablesRelative()) {
if (drawable != null) {
drawable.setColorFilter(new PorterDuffColorFilter(ContextCompat.getColor(textView.getContext(),color), PorterDuff.Mode.SRC_IN));
}
}
}
使用
setTextViewDrawableColor(textView1,R.color.AccentColor)
KOTLIN
private fun setTextViewDrawableColor(@NonNull textView: TextView, @ColorRes color: Int) {
for (drawable in textView.compoundDrawablesRelative) {
if (drawable != null) {
drawable.colorFilter = PorterDuffColorFilter(ContextCompat.getColor(textView.context, color), PorterDuff.Mode.SRC_IN)
}
}
}
使用
setTextViewDrawableColor(textView1,R.color.AccentColor)
KOTLIN 扩展
fun TextView.setDrawableColor(@ColorRes color: Int) {
compoundDrawablesRelative.filterNotNull().forEach {
it.colorFilter = PorterDuffColorFilter(ContextCompat.getColor(this.context, color), PorterDuff.Mode.SRC_IN)
}
}
使用
textView1.setDrawableColor(R.color.colorAccent)
只有 XML API => 23
android:backgroundTintMode="src_in"
android:drawableTint="FF0000"