在html-textview中如何创建继承抽象类的匿名对象新实例?
问题描述
我在使用旧的html-textview库时,原本用如下代码实现多table标签在TextView中渲染多个可点击的table span,通过newInstance()方法来获取每个span的点击事件:
htmlTxtV.setClickableTableSpan(ClickableTableSpanImpl(intentDomain)) inner class ClickableTableSpanImpl(private val intentDomain: WordPressPostDataDomain) : ClickableTableSpan() { override fun newInstance(): ClickableTableSpan { return ClickableTableSpanImpl(intentDomain) } override fun onClick(widget: View) { // 执行点击逻辑 } }
改成匿名对象实现后:
setClickableTableSpan(object : ClickableTableSpan() { override fun newInstance(): ClickableTableSpan { return this } override fun onClick(widget: View) { // 执行点击逻辑 } })
这时只能收到最后一个span的回调,说明return this和return ClickableTableSpanImpl()并不等价。请问仅通过匿名对象能否创建新实例?
回答
匿名对象本身是单例的,在定义它的位置只会被创建一次,所以你在newInstance()里返回this,本质是把同一个对象实例重复绑定给所有table span,最终所有点击事件都会指向这同一个实例,表现为只能收到最后一个span的回调。
仅靠单个匿名对象没办法创建新实例——匿名对象没有构造函数,无法通过常规方式生成新的实例。如果想继续用匿名类的写法,可以通过闭包捕获参数,在newInstance()里重新创建新的匿名对象:
setClickableTableSpan(object : ClickableTableSpan() { private val capturedDomain = intentDomain override fun newInstance(): ClickableTableSpan { // 每次调用newInstance都生成全新的匿名对象,同时捕获同一个参数 return object : ClickableTableSpan() { override fun newInstance(): ClickableTableSpan { return this@newInstance } override fun onClick(widget: View) { // 使用capturedDomain执行点击逻辑 } } } override fun onClick(widget: View) { // 初始实例的点击逻辑,和newInstance创建的保持一致 } })
不过这种嵌套匿名对象的写法可读性较差,更简洁可靠的方案还是用你最初的命名内部类实现,它能通过构造函数清晰生成新实例,逻辑更直观。
内容的提问来源于stack exchange,提问作者Bitwise DEVS
相关产品推荐
相关产品推荐

