web-dev-qa-db-fra.com

kotlin-extensions-Android dans ViewHolder

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

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

comme ce code, Kotlin a-t-il une mémoire cache dans les extensions Android?

quand je décompile le bytecode de 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());

}

cela signifie que lorsque j'ai appelé binData dans Adapter.onBindViewHolder (), il s'appellera findViewById à chaque fois

Cela augmente considérablement la perte de performance , et n'atteint pas l'objectif de réutilisation de la mise en page.

Kotlin a-t-il une logique de cache dans les extensions Android avec ViewHolder?

11
Werb

Afficher la mise en cache dans une ViewHolder ou toute classe personnalisée est possible uniquement à partir de Kotlin 1.1.4 et il est actuellement au stade expérimental.

  1. Mettez à jour votre version de Kotlin dans votre fichier build.gradle de niveau racine.

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

  1. Ajoutez ces lignes dans votre application build.gradle:

androidExtensions { experimental = true }

  1. Héritez de votre ViewHolder classe de LayoutContainer. LayoutContainer est une interface disponible dans le package kotlinx.Android.extensions

  2. Ajoutez les importations ci-dessous, où view_item est le nom de la présentation. 

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

La classe ViewHolder entière ressemble à ceci:

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

Le code Java décompilé montre que cette classe utilise le cache pour les vues:

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

Autres lectures: Proposition KEEP , un tutoriel génial

24
Bob

De mon point de vue, kotlin-Android-extensions est simplement une extension importée de manière statique (codes générés) pour remplacer View.findViewById.

Je vous recommanderais de stocker les références dans votre support de vue. 

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

L'un des avantages de cette approche est que tout type d'incompatibilité sera découvert lors de la compilation!

6
Gary LO

Dans votre projet gradé: -

 buildscript {
        ext.kotlin_version = '1.2.41'

        repositories {
            google()
            jcenter()
        }

et dans votre application:

apply plugin: 'kotlin-Android'
apply plugin: 'kotlin-Android-extensions'

Android {}
dependencies {
  compile "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"

Après cela, vous pouvez utiliser dans votre activité:

import kotlinx.Android.synthetic.main.unit_preferences_activity.*

et:

  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