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 中查看缓存,目前处于实验阶段。

  1. 在您的根级别 build.gradle 文件中更新您的 Kotlin 版本

classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.1.4-3"

  1. 在您的应用中添加这些行 build.gradle:

androidExtensions { experimental = true }

  1. LayoutContainer继承你的ViewHolderclass。 LayoutContainerkotlinx.android.extensions 包中可用的接口。

  2. 添加以下导入,其中 view_item 是布局名称。

import kotlinx.android.synthetic.main.view_item.* import kotlinx.android.synthetic.main.view_item.view.*

整个ViewHolderclass看起来像:

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()
            }

        }