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的范围?
答案 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);
这正是我想要的。