我可以使用Kotlin Android Extension推迟适配器中的视图绑定

时间:2017-12-26 10:27:12

标签: android kotlin kotlin-android-extensions

Kotlin Android Extensions提供了一种直接在Activity / fragment / Adapters中使用ID的方法。 所以我想要的是适配器的通用方法,并将绑定视图责任留给适配器的用户而不是适配器本身。 例如:

UsersRunner.java

我可以直接传递布局文件和绑定函数来绑定适配器,而无需为每个布局文件和适配器重写相同的代码。

但问题是: ViewHolder模式想要消除调用" findViewById"每次ChildView充气。但随着我的适配器的实现。它需要调用" findViewById"每次适配器绑定视图时。

编辑:有关"缓存的详细信息"问题

在活动中使用class GenericAdapter<T>( @LayoutRes private val layoutId: Int, private var list: List<T>, inline private val bind: (View, T, Int) -> Unit) : RecyclerView.Adapter<InnerHolder>() { override fun onBindViewHolder(holder: InnerHolder?, position: Int) { holder?.containerView?.let { bind(holder.containerView, list[position], position) } } override fun onCreateViewHolder(parent: ViewGroup?, viewType: Int): InnerHolder = InnerHolder(LayoutInflater.from(parent?.context).inflate(layoutId, parent, false)) override fun getItemCount(): Int = list.size class InnerHolder( val containerView: View?) : RecyclerView.ViewHolder(containerView) } 。喜欢

GenericAdapter

这会反编译成:

override fun onCreated(savedInstanceState: Bundle?){
    list.adapter = GenericAdapter<Item>(items){ view,item,position ->
        view.textview.text = item.text
    }
}

但是他们有一个带有Android扩展程序的实验工具,例如 TextView var2 = (TextView)var10000.findViewById(id.textview); Intrinsics.checkExpressionValueIsNotNull(var2, "itemView.tv_text"); var2.setText((CharSequence)String.valueOf(var1));

LayoutContainer

这将完美地使用缓存的视图:

class InnerHolder(
    override val containerView: View?) : RecyclerView.ViewHolder(containerView), LayoutContainer {
    fun bind(int: Int) {
        textview.text = int.toString()
    }
}

但问题是缓存的视图需要在LayoutContainer的范围内。例如,这种实现不起作用:

     TextView var10000 = (TextView)this._$_findCachedViewById(id.tv_text);

这仍然会使用findViewById来查找视图:

class InnerHolder(
    override val containerView: View?) : RecyclerView.ViewHolder(containerView), LayoutContainer {
    fun bind(int: Int) {
        this.bindInt(int)
    }

}
// some extension function outside the ViewHolder Scope. 
fun LayoutContainer.bindInt(int: Int) {
    tv_text.text = int.toString()

}

所以我的问题是有没有办法以某种方式保留缓存,仍然使用Android扩展程序和我的适配器,但超出了viewholder的范围?

2 个答案:

答案 0 :(得分:1)

您可以这样使用:

innerHolder.apply {
    tv_text.text = "test"
}

它会反编译成:

TextView var10000 = (TextView)innerHolder._$_findCachedViewById(id.tv_text);
var10000.setText((CharSequence)"test");

答案 1 :(得分:0)

受@linx的启发

如果我只是为InnerHolder而不是LayoutContainer创建扩展功能。上下文为Android Extension提供了足够的信息来获取缓存视图。

class InnerHolder(
    override val containerView: View?) : RecyclerView.ViewHolder(containerView), LayoutContainer {
    fun bind(int: Int) {
        this.bindInt(int)
    }

}
// some extension function outside the ViewHolder Scope. 
fun InnerHolder.bindInt(int: Int) {
    tv_text.text = int.toString()

}

这将编译成

TextView var10000 = (TextView)$receiver._$_findCachedViewById(id.tv_text);

这正是我想要的。