Android开发:如何从TextView获取其绑定的string资源键名而非实际值
问题解答
结论先行
- 直接从已渲染完成的标准TextView中无法直接获取布局阶段绑定的string资源键名,系统在布局inflate时会将
@string/yes解析为实际字符串值赋值给控件,原始资源ID默认不会留存 - 可以通过字符串实际值反向查询资源键名,但存在严重的局限性,不推荐生产环境使用
- 更可靠的方案是通过自定义控件提前留存资源ID,再转译得到资源键名
方案1:字符串值反向查询资源键(不推荐)
局限性
- 若存在多个string资源键对应相同字符串值,会返回多个匹配结果,无法确定对应哪个
- 受应用多语言配置影响,同一资源键在不同语言下字符串值不同,查询结果会随系统语言变化
实现代码
fun getStringResKeyByValue(context: Context, targetValue: String): List<String> { val res = context.resources val matchKeys = mutableListOf<String>() // 遍历所有string类型资源 val fields = R.string::class.java.declaredFields for (field in fields) { try { val resId = field.getInt(null) val resValue = res.getString(resId) if (resValue == targetValue) { // 获取资源键名 matchKeys.add(res.getResourceEntryName(resId)) } } catch (e: Exception) { continue } } return matchKeys }
调用示例:val keys = getStringResKeyByValue(context, tvText.text.toString())
方案2:自定义TextView留存资源ID(推荐)
在布局加载阶段直接读取android:text属性绑定的资源ID并留存,后续可直接转译为准确的资源键名,不受任何外部因素影响
自定义控件代码
class StringIdTextView @JvmOverloads constructor( context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0 ) : AppCompatTextView(context, attrs, defStyleAttr) { // 存储绑定的string资源ID var textStringResId: Int = 0 private set init { attrs?.let { val typedArray = context.obtainStyledAttributes(it, intArrayOf(android.R.attr.text)) val resId = typedArray.getResourceId(0, 0) if (resId != 0 && typedArray.getString(0) == context.getString(resId)) { textStringResId = resId } typedArray.recycle() } } override fun setText(resId: Int) { super.setText(resId) textStringResId = resId } }
布局使用
<com.yourpackage.StringIdTextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/tvText" android:text="@string/yes"/>
获取键名代码
val resKey = resources.getResourceEntryName(tvText.textStringResId)
// 直接得到"yes"
内容的提问来源于stack exchange,提问作者GoonerJhh
相关产品推荐
相关产品推荐

