web-dev-qa-db-ja.com

ViewHolderのkotlin-Android-extensions

class MyViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {

       fun bindata(text: SingleText){
            itemView.title.text = text.title
            itemView.desc.text = text.desc
       }
}

このコードのように、KotlinにはAndroid拡張機能にキャッシュがありますか?

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拡張機能にキャッシュロジックがありますか?

14
Werb

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. ViewHolderからLayoutContainerクラスを継承します。 LayoutContainerは、kotlinx.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プロポーザル素晴らしいチュートリアル

28
Bob

私の理解では、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
   }
}

このアプローチの利点の1つは、コンパイル時に型の不一致が発見されることです!

10
Gary LO

プロジェクト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"

これらの後、あなたはあなたの活動で使用できます:

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

        }
0
abhilasha Yadav