Kotlin通用ViewHolder绑定对象至TextView的赋值问题及解决方案
通用RecyclerView ViewHolder对象绑定TextView的问题与解决方案
问题背景
我实现了一个通用RecyclerView ViewHolder,目标是把任意对象绑定到对应视图上。目前已完成从对象读取数据、从视图绑定类获取字段名的操作,但在为TextView赋值objectValue时遇到阻碍。
最初的思路是遍历绑定类的字段,调用对象的属性读取方法(布局元素与对象字段同名),但尝试通过反射访问binding字段并调用setText时,出现类型转换等异常。
最初的代码实现:
class UniversalViewHolder<T : Any>(val bindingAny: ViewDataBinding) : RecyclerView.ViewHolder(bindingAny.root){ fun bind(elemAny: Any){ var binding = bindingAny.javaClass binding.fields.forEach { try { val objectValue = readInstanceProperty<String>(elemAny,it.name) Log.d(TAG,it.name+" "+objectValue) if (it.type == TextView::class.java){ // 此处尝试绑定但失败 } }catch (ex: NoSuchElementException){ Log.e(TAG, "NO ELEMENT AT THIS FIELD "+ it.name) }catch (ex:Exception){ Log.e(TAG,"CRASH AT THIS ELEM: " + it.name+"\n"+ex.stackTraceToString()) } } } }
遇到的具体问题
- 通过
binding.fields获取Field对象后,无法直接修改TextView的文本内容 - 调用
setText方法时触发类型转换异常
最终解决方案
通过递归遍历视图树,收集所有TextView(包括MaterialTextView),再通过资源名称匹配字段名的方式,将对应数据赋值给目标TextView。
完整实现代码
1. 更新后的绑定方法
fun bind(elemAny: Any,context: Context){ val binding = bindingAny.javaClass binding.fields.forEach { field -> try { val objectValue = readInstanceProperty<String>(elemAny,field.name) Log.d(TAG,field.name+" "+objectValue) if (field.type == TextView::class.java){ arrayTextView.forEach { if(context.resources.getResourceName(it.id).contains(field.name)){ it.text = objectValue } } } }catch (ex: NoSuchElementException){ Log.e(TAG, "NO ELEMENT AT THIS FIELD "+ field.name) }catch (ex:Exception){ Log.e(TAG,"CRASH AT THIS ELEM: " + field.name+"\n"+ex.stackTraceToString()) } } }
2. 视图树遍历收集TextView方法
private var arrayTextView : ArrayList<TextView> = ArrayList() private fun searchLeaf(root: ViewGroup,context: Context){ while(true){ root.forEach { if(it::class == MaterialTextView::class || it::class == TextView::class){ Log.d(TAG,context.resources.getResourceName(it.id)) arrayTextView.add(it as TextView) } else if((it as ViewGroup).size != 0){ try{ searchLeaf(it as ViewGroup,context) }catch (ex:Exception){ } } } break } }
内容的提问来源于stack exchange,提问作者Daniel
相关产品推荐
相关产品推荐

