class MyViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
fun bindata(text: SingleText){
itemView.title.text = text.title
itemView.desc.text = text.desc
}
}
wie dieser Code hat Kotlin einen Cache in Android-Erweiterungen?
wenn ich kotlin bytecode dekompiliere
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());
}
das heißt, wenn ich in Adapter.onBindViewHolder () binData aufrief, wird es jedes Mal findViewById aufrufen
Dies erhöht den Leistungsverlust signifikant und es wird nicht der Zweck der Layoutwiederverwendung erreicht
Kotlin hat eine Cache-Logik in Android-Erweiterungen mit ViewHolder?
Das Anzeigen von Caching in einer ViewHolder
oder einer benutzerdefinierten Klasse ist nur ab Kotlin 1.1.4 möglich und befindet sich derzeit im experimentellen Stadium.
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.1.4-3"
build.gradle
:androidExtensions {
experimental = true
}
Vererben Sie Ihre ViewHolder
-Klasse von LayoutContainer
. LayoutContainer
ist eine Schnittstelle, die im kotlinx.Android.extensions
-Paket verfügbar ist.
Fügen Sie die folgenden Importe hinzu, wobei view_item
der Name des Layouts ist.
import kotlinx.Android.synthetic.main.view_item.*
import kotlinx.Android.synthetic.main.view_item.view.*
Die gesamte ViewHolder
-Klasse sieht folgendermaßen aus:
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
}
}
Der dekompilierte Java-Code zeigt, dass diese Klasse einen Cache für die Views verwendet:
public final void bind(@NotNull String title) {
Intrinsics.checkParameterIsNotNull(title, "title");
((TextView)this._$_findCachedViewById(id.itemTitle)).setText((CharSequence)"Hello Kotlin!");
}
Weitere Lesungen: KEEP-Vorschlag , ein tolles Tutorial .
Nach meinem Verständnis ist kotlin-Android-Erweiterungen nur eine statisch importierte Erweiterung (generierte Codes), die View.findViewById ersetzt.
Ich würde Ihnen empfehlen, die Referenzen in Ihrem Ansichtshalter zu speichern.
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
}
}
Einer der Vorteile dieses Ansatzes ist, dass jede Art von Abweichung in der Kompilierzeit entdeckt wird!
In Ihrem Projektabschluss: -
buildscript {
ext.kotlin_version = '1.2.41'
repositories {
google()
jcenter()
}
und in deinem app gradle:
apply plugin: 'kotlin-Android'
apply plugin: 'kotlin-Android-extensions'
Android {}
dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
Nach diesen können Sie in Ihrer Aktivität verwenden:
import kotlinx.Android.synthetic.main.unit_preferences_activity.*
und:
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()
}
}