【发布时间】:2017-12-26 10:27:11
【问题描述】:
Kotlin Android 扩展提供了一种直接在 Activity/fragment/Adapters 中使用 ID 的方法。 所以我想要的是适配器的通用方式,并将绑定视图的责任留给适配器的用户而不是适配器本身。 例如:
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)
}
我可以根据需要传递布局文件和绑定函数来绑定适配器,而无需使用适配器为每个布局文件重写相同的代码。
但这里有问题: ViewHolder 模式希望在每次 ChildView 膨胀时消除调用“findViewById”。但是随着我的适配器实现。每次adapter绑定view都需要调用findViewById。
编辑:关于“缓存”问题的详细信息。
在活动中使用GenericAdapter。喜欢
override fun onCreated(savedInstanceState: Bundle?){
list.adapter = GenericAdapter<Item>(items){ view,item,position ->
view.textview.text = item.text
}
}
这会反编译成这样:
TextView var2 = (TextView)var10000.findViewById(id.textview);
Intrinsics.checkExpressionValueIsNotNull(var2, "itemView.tv_text");
var2.setText((CharSequence)String.valueOf(var1));
但他们有一个带有 Android 扩展的实验工具,例如 LayoutContainer:
class InnerHolder(
override val containerView: View?) : RecyclerView.ViewHolder(containerView), LayoutContainer {
fun bind(int: Int) {
textview.text = int.toString()
}
}
这将完美地使用缓存的视图:
TextView var10000 = (TextView)this._$_findCachedViewById(id.tv_text);
但问题是缓存视图需要在 LayoutContainer 的范围内。例如,此实现将不起作用:
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()
}
这仍将使用 findViewById 来查找视图:
TextView var10000 = (TextView)$receiver.getContainerView().findViewById(id.tv_text);
所以我的问题是有没有办法以某种方式保留缓存,并且仍然在我的适配器上使用 Android 扩展,但超出了 viewholder 的范围?
【问题讨论】:
-
您可以将所有
View引用保存在 holder 类中,并仅在init块中调用findViewById。 -
请考虑更新您的问题以反映给定的歧义。还要添加实例化适配器的用例。或许我稍后会找到答案……
-
@tynn 是的。检查更新。感谢您的宝贵时间!
标签: android kotlin kotlin-android-extensions