kotlin-android-ViewHolder 中的扩展
kotlin-android-extensions in ViewHolder
class MyViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
fun bindata(text: SingleText){
itemView.title.text = text.title
itemView.desc.text = text.desc
}
}
像这段代码,Kotlin 在 android-extensions 中有缓存吗?
当我反编译 kotlin 字节码时
public final void bindata(@NotNull SingleText text) {
Intrinsics.checkParameterIsNotNull(text, "text");
((AppCompatTextView)this.itemView.findViewById(id.title)).setText((CharSequence)text.getTitle());
((AppCompatTextView)this.itemView.findViewById(id.desc)).setText((CharSequence)text.getDesc());
}
这意味着当我在Adapter.onBindViewHolder()中调用binData时,它每次都会调用findViewById
这样明显增加了性能的损失,并且没有达到布局重用的目的
Kotlin 在 android-ViewHolder 扩展中有任何缓存逻辑吗?
根据我的理解,kotlin-android-extensions 只是一个静态导入的扩展(生成的代码)来替换 View.findViewById.
我建议您将引用存储在视图持有者中。
class MyViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
val title: TextView = itemView.title
val desc: TextView = itemView.desc
fun bindata(text: SingleText){
title.text = text.title
desc.text = text.desc
}
}
这种方法的好处之一是任何类型不匹配都会在编译时被发现!
只有 Kotlin 1.1.4 才能在 ViewHolder
或任何自定义 class 中查看缓存,目前处于实验阶段。
- 在您的根级别 build.gradle 文件中更新您的 Kotlin 版本
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.1.4-3"
- 在您的应用中添加这些行
build.gradle
:
androidExtensions {
experimental = true
}
从LayoutContainer
继承你的ViewHolder
class。 LayoutContainer
是 kotlinx.android.extensions
包中可用的接口。
添加以下导入,其中 view_item
是布局名称。
import kotlinx.android.synthetic.main.view_item.*
import kotlinx.android.synthetic.main.view_item.view.*
整个ViewHolder
class看起来像:
class ViewHolder(override val containerView: View) : RecyclerView.ViewHolder(containerView),
LayoutContainer {
fun bind(title: String) {
itemTitle.text = "Hello Kotlin!" // itemTitle is the id of the TextView in the layout
}
}
反编译的 Java 代码显示此 class 使用视图缓存:
public final void bind(@NotNull String title) {
Intrinsics.checkParameterIsNotNull(title, "title");
((TextView)this._$_findCachedViewById(id.itemTitle)).setText((CharSequence)"Hello Kotlin!");
}
进一步阅读:KEEP proposal, an awesome tutorial。
在你的项目中gradle:-
buildscript {
ext.kotlin_version = '1.2.41'
repositories {
google()
jcenter()
}
在您的应用中 gradle:
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
android {}
dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
这些之后你就可以用在你身上了 activity :
import kotlinx.android.synthetic.main.unit_preferences_activity.*
和:
private fun setClickListener() {
rlCaloriesBurnt.setOnClickListener{
launchActivity(CaloriesBurntPrefreenceUnit::class.java)
}
rlDistanceTravelled.setOnClickListener{
tvDistanceUnit.text=resources.getString(R.string.km)
launchActivity(DistanceTravelledUnit::class.java)
}
rlWaterConsumption.setOnClickListener{
launchActivity(WaterPreferenceUnit::class.java)
}
backArrow.setOnClickListener{
finish()
}
}
class MyViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
fun bindata(text: SingleText){
itemView.title.text = text.title
itemView.desc.text = text.desc
}
}
像这段代码,Kotlin 在 android-extensions 中有缓存吗?
当我反编译 kotlin 字节码时
public final void bindata(@NotNull SingleText text) {
Intrinsics.checkParameterIsNotNull(text, "text");
((AppCompatTextView)this.itemView.findViewById(id.title)).setText((CharSequence)text.getTitle());
((AppCompatTextView)this.itemView.findViewById(id.desc)).setText((CharSequence)text.getDesc());
}
这意味着当我在Adapter.onBindViewHolder()中调用binData时,它每次都会调用findViewById
这样明显增加了性能的损失,并且没有达到布局重用的目的
Kotlin 在 android-ViewHolder 扩展中有任何缓存逻辑吗?
根据我的理解,kotlin-android-extensions 只是一个静态导入的扩展(生成的代码)来替换 View.findViewById.
我建议您将引用存储在视图持有者中。
class MyViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
val title: TextView = itemView.title
val desc: TextView = itemView.desc
fun bindata(text: SingleText){
title.text = text.title
desc.text = text.desc
}
}
这种方法的好处之一是任何类型不匹配都会在编译时被发现!
只有 Kotlin 1.1.4 才能在 ViewHolder
或任何自定义 class 中查看缓存,目前处于实验阶段。
- 在您的根级别 build.gradle 文件中更新您的 Kotlin 版本
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.1.4-3"
- 在您的应用中添加这些行
build.gradle
:
androidExtensions {
experimental = true
}
从
LayoutContainer
继承你的ViewHolder
class。LayoutContainer
是kotlinx.android.extensions
包中可用的接口。添加以下导入,其中
view_item
是布局名称。
import kotlinx.android.synthetic.main.view_item.*
import kotlinx.android.synthetic.main.view_item.view.*
整个ViewHolder
class看起来像:
class ViewHolder(override val containerView: View) : RecyclerView.ViewHolder(containerView),
LayoutContainer {
fun bind(title: String) {
itemTitle.text = "Hello Kotlin!" // itemTitle is the id of the TextView in the layout
}
}
反编译的 Java 代码显示此 class 使用视图缓存:
public final void bind(@NotNull String title) {
Intrinsics.checkParameterIsNotNull(title, "title");
((TextView)this._$_findCachedViewById(id.itemTitle)).setText((CharSequence)"Hello Kotlin!");
}
进一步阅读:KEEP proposal, an awesome tutorial。
在你的项目中gradle:-
buildscript {
ext.kotlin_version = '1.2.41'
repositories {
google()
jcenter()
}
在您的应用中 gradle:
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
android {}
dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
这些之后你就可以用在你身上了 activity :
import kotlinx.android.synthetic.main.unit_preferences_activity.*
和:
private fun setClickListener() {
rlCaloriesBurnt.setOnClickListener{
launchActivity(CaloriesBurntPrefreenceUnit::class.java)
}
rlDistanceTravelled.setOnClickListener{
tvDistanceUnit.text=resources.getString(R.string.km)
launchActivity(DistanceTravelledUnit::class.java)
}
rlWaterConsumption.setOnClickListener{
launchActivity(WaterPreferenceUnit::class.java)
}
backArrow.setOnClickListener{
finish()
}
}