【问题标题】:kotlin-android-extensions in ViewHolderViewHolder 中的 kotlin-android-extensions
【发布时间】:2018-02-07 15:49:07
【问题描述】:
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 在带有 ViewHolder 的 android-extensions 中有任何缓存逻辑吗?

【问题讨论】:

  • findViewById 找到已创建的视图。所以这意味着你正在重用它。没有您所说的性能问题。

标签: android android-recyclerview kotlin adapter kotlin-android-extensions


【解决方案1】:

ViewHolder 或任何自定义类中的视图缓存只能来自 Kotlin 1.1.4,并且目前处于实验阶段。

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

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

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

androidExtensions { experimental = true }

  1. LayoutContainer 继承您的ViewHolder 类。 LayoutContainerkotlinx.android.extensions 包中的一个接口。

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

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

整个ViewHolder 类看起来像:

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 代码显示该类对视图使用缓存:

    public final void bind(@NotNull String title) {
          Intrinsics.checkParameterIsNotNull(title, "title");
          ((TextView)this._$_findCachedViewById(id.itemTitle)).setText((CharSequence)"Hello Kotlin!");
    }

进一步阅读:KEEP proposalan awesome tutorial

【讨论】:

    【解决方案2】:

    据我了解,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
       }
    }
    

    这种方法的一个好处是任何类型不匹配都会在编译时被发现!

    【讨论】:

    • 如果为每个View添加一行代码,还不如不使用Kotlin Android扩展。如果将 findViewById() 包装在扩展函数中,它也将是类型安全的。 val title = itemView.find<TextView>(R.id.title)
    • @FrankHarper 如果R.id.title 没有指向TextView,假设指向ImageView。 itemView.find<TextView>(R.id.title) 仍会编译并会导致运行时崩溃,而使用 Kotlin Android 扩展会在编译时抛出错误。
    【解决方案3】:

    在你的项目中:-

     buildscript {
            ext.kotlin_version = '1.2.41'
    
            repositories {
                google()
                jcenter()
            }
    

    在你的应用程序中:

    apply plugin: 'kotlin-android'
    apply plugin: 'kotlin-android-extensions'
    
    android {}
    dependencies {
      compile "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
    

    在这些之后你可以在你的活动中使用:

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

    【讨论】:

      猜你喜欢
      • 2017-12-16
      • 1970-01-01
      • 1970-01-01
      • 2023-04-03
      • 2021-03-18
      • 2021-12-22
      • 2020-02-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多