Android TextView的颜色和字体自适应

前言

最近比较忙,没有时间去梳理一些硬核的东西,今天就来分享一些简单有意思的技巧。拿TextView来说,平时我们都会在特定的场景去设置它的字体颜色和字体大小。那么有没有一种办法能够一劳永逸不用每次都去设置,能让TextView自己去根据自身的控件属性去自适应颜色和大小呢?当然是有的,这里可以简单的分享一些思路。

1. 字体大小自适应

TextView可以根据让字体的大小随着宽高进行自适应。

设置大小自适应的方式很简单,只需要添加这3行代码即可

ini 复制代码
android:autoSizeMaxTextSize="22dp"  
android:autoSizeMinTextSize="8dp"  
android:autoSizeTextType="uniform"

我们可以来看看效果,我给宽高都设置不同的值,能看到字体大小变化的效果

ini 复制代码
android:layout_width="50dp"  
android:layout_height="20dp"
ini 复制代码
android:layout_width="50dp"  
android:layout_height="30dp"
ini 复制代码
android:layout_width="50dp"  
android:layout_height="50dp"
ini 复制代码
android:layout_width="80dp"  
android:layout_height="80dp"

最后这里可以看到autoSizeMaxTextSize的效果

这里可以多提一句,一般这种字体随宽高自适应的场景在正常开发中比较少见。如果你的项目合理的话,一般字体的大小都是固定那几套,所以把字体大小定义到资源文件中,甚至通过style的方式去设置,才是最节省时间的方式。

2. 字体颜色自适应

关于字体的颜色自适应,如果你真想把这套东西搞起来,你就需要对"颜色"这个概念有一定的深层次的了解。我这里就只简单做一些效果来举例。

我这里演示Textview根据背景颜色来自动设置字体颜色是白色还是黑色,当背景颜色是暗色时(比如黑色),字体颜色变成白色,当背景颜色是亮色时(比如白色),字体颜色变成黑色。

那么首先需要有个概念:我怎么判断背景是亮色还是暗色?

这就需要对颜色有一定的理解。要判断一个颜色是暗色还是亮色,可以通过计算颜色的亮度来实现。一种常见的方法是将RGB颜色值转换为灰度值,然后根据灰度值来判断颜色的深浅程度。

灰度值的计算公式 灰度值 = 0.2126 * R + 0.7152 * G + 0.0722 * B

根据这个公式,我们能封装一个判断颜色是否是亮色的方法

kotlin 复制代码
private fun isLightColor(color: Int): Boolean {  
    val r = color shr 16 and 0xFF  
    val g = color shr 8 and 0xFF  
    val b = color and 0xFF  
    val luminance = (0.2126 * r + 0.7152 * g + 0.0722 * b) / 255  
    return luminance > 0.5
}

如果觉得这个判断不太符合你心里的预期,可以修改最后一行的luminance > 0.5值

下一步,我们需要获取控件的背景,然后从背景中获取颜色值。

获取背景直接调用

ini 复制代码
val d = textView?.background

根据Drawable去获取颜色

kotlin 复制代码
private fun getColorByDrawable(d : Drawable) : Int{  
    val bitmap = Bitmap.createBitmap(  
        textView?.width ?: 0,  
        textView?.height ?: 0,  
        Bitmap.Config.ARGB_8888  
    )
    val canvas = Canvas(bitmap)  
    d.setBounds(0, 0, canvas.width, canvas.height)  
    d.draw(canvas)  
    return bitmap.getPixel(0, 0)  
}

注意,我这里不考虑渐变色的情况,只是考虑单色的情况,所以x和y是传0,一般对于复杂的渐变色也不好做适配,但是对于background分边框和填充两种颜色的情况,一般文字都是显示在填充区域,这时候的x和y可以去根据边框宽度去加个偏移量(总之可以灵活应变)

还有一种场景,对于TextView没背景颜色,是它的父布局有背景颜色的情况,可以循环去调用父布局的view.background判断是否为空,为空就循环一次,不为空直接获取颜色。我这里就不演示代码了。

这里先把全部代码贴出来(都是用了最简单的方式)

kotlin 复制代码
override fun onCreate(savedInstanceState: Bundle?) {  
    super.onCreate(savedInstanceState)  
    setContentView(R.layout.activity_demo_text)  
  
    textView = findViewById(R.id.tv)  
    val d = textView?.background  
    textView?.post {  
        if (d != null){  
            if (isLightColor(getColorByDrawable(d))){  
                textView?.setTextColor(resources.getColor(R.color.black))  
            }else{  
                textView?.setTextColor(resources.getColor(R.color.white))  
            }  
        }  
    }  
}

private fun getColorByDrawable(d : Drawable) : Int{  
    val bitmap = Bitmap.createBitmap(  
        textView?.width ?: 0,  
        textView?.height ?: 0,  
        Bitmap.Config.ARGB_8888  
    )
    val canvas = Canvas(bitmap)  
    d.setBounds(0, 0, canvas.width, canvas.height)  
    d.draw(canvas)  
    return bitmap.getPixel(0, 0)  
}

private fun isLightColor(color: Int): Boolean {  
    val r = color shr 16 and 0xFF  
    val g = color shr 8 and 0xFF  
    val b = color and 0xFF  
    val luminance = (0.2126 * r + 0.7152 * g + 0.0722 * b) / 255  
    return luminance > 0.5
}

然后改几个背景色来看看效果

ini 复制代码
android:background="#000000"
ini 复制代码
android:background="#ffffff"
ini 复制代码
android:background="#3377ff"
ini 复制代码
android:background="#ee7700"
相关推荐
信徒_12 分钟前
Mysql 在什么样的情况下会产生死锁?
android·数据库·mysql
大胡子的机器人1 小时前
安卓中app_process运行报错Aborted,怎么查看具体的报错日志
android
goto_w1 小时前
uniapp上使用webview与浏览器交互,支持三端(android、iOS、harmonyos next)
android·vue.js·ios·uni-app·harmonyos
QING6182 小时前
Kotlin Random.Default用法及代码示例
android·kotlin·源码阅读
QING6182 小时前
Kotlin Byte.inc用法及代码示例
android·kotlin·源码阅读
QING6182 小时前
Kotlin contentEquals用法及代码示例
android·kotlin·源码阅读
每次的天空10 小时前
Android学习总结之算法篇四(字符串)
android·学习·算法
x-cmd11 小时前
[250331] Paozhu 发布 1.9.0:C++ Web 框架,比肩脚本语言 | DeaDBeeF 播放器发布 1.10.0
android·linux·开发语言·c++·web·音乐播放器·脚本语言
tangweiguo0305198715 小时前
Android BottomNavigationView 完全自定义指南:图标、文字颜色与选中状态
android
遥不可及zzz16 小时前
Android 应用程序包的 adb 命令
android·adb