Sintético Kotlin en Adaptador o ViewHolder

84

Soy nuevo en Kotlin. Encontré y traté de usar un método sintético en lugar de un método molesto findViewByIden mi Activityclase, pero encontré "Si queremos llamar a las propiedades sintéticas en la Vista (útil en las clases de adaptadores), también deberíamos importar kotlinx.android.synthetic.main .ver.*." ¿Pero no puedo entender cómo funciona exactamente? ¿Hay ejemplos?

ocupado
fuente
Puede consultar este blog o este ejemplo
Cabezas

Respuestas:

96

Ejemplo simple de https://github.com/antoniolg/Kotlin-for-Android-Developers

import kotlinx.android.synthetic.item_forecast.view.*

class ForecastListAdapter() : RecyclerView.Adapter<ForecastListAdapter.ViewHolder>() {

    class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {

        fun bindForecast(forecast: Forecast) {
            itemView.date.text = forecast.date.toDateString()
        }
    }
}

No es necesario escribir

val view = itemView.findViewById(R.id.date) as TextView
view.text = forecast.date.toDateString()

Sólo

itemView.date.text = forecast.date.toDateString()

¡Simple y eficaz!

Peter Zhao
fuente
4
bien, esta podría ser una pregunta tonta, pero ¿de dónde viene la referencia 'itemView'?
Saulo Aguiar
4
No hay caché para las extensiones de vista, por lo que las referencias a las vistas deben almacenarse en caché, como en viewHolder normal.
Miha_x64
21
desafortunadamente, eso es llamar a findViewById en cada llamada bind (): medium.com/proandroiddev/…
Miguel Beltran
2
@Mike desde Kotlin 1.1.4 todas las vistas se almacenarán en caché. Incluso en ViewHolders. El artículo que publicaste también menciona esto.
Stefan Medack
2
@StefanMedack Soy el autor del artículo :) Aunque debo señalar que es solo una parte de las funciones experimentales y debe habilitarse manualmente. Aún no lo he probado.
Miguel Beltran
37

Kotling 1.1.4 fuera

Más información: https://antonioleiva.com/kotlin-android-extensions/

Necesita habilitar las extensiones de Android Kotlin agregando esto a su build.gradle:

apply plugin: 'org.jetbrains.kotlin.android.extensions'
androidExtensions {
    experimental = true
}

Desde esta nueva versión de Kotlin, las Extensiones de Android han incorporado algunas características nuevas e interesantes: cachés en cualquier clase (que curiosamente incluye ViewHolder)

Usándolo en un ViewHolder (o cualquier clase personalizada). Tenga en cuenta que esta clase debe implementar la LayoutContainerinterfaz:

class ViewHolder(override val containerView: View) : RecyclerView.ViewHolder(containerView), 
        LayoutContainer {

    fun bind(title: String) {
        itemTitle.text = "Hello Kotlin!"
    }
}
Dhaval Jivani
fuente
3
Agregando a esta información: Según Kotlin 1.1.4, la función es experimental y debe habilitarse en el archivo build.gradle
Miguel Beltran
2
¿Es esto experimental más? Quiero usar esto en el código de producción
Carson Holzheimer
@CarsonHolzheimer esta función aún es experimental
the_dani
parece que ni siquiera funciona 1.3.21. Creo que no lo van a implementar
user924
pero podemos usar containerView.itemTitle.text = "Hello Kotlin!"y creo que es suficiente
user924
11

Necesitas

import kotlinx.android.synthetic.row_wall.view.*

Y luego algo como:

convertView.titleText.text = item.title

El punto es que view. * Introduce extensiones a la clase View.

Zsolt Szatmari
fuente
1
ya se dio la respuesta stackoverflow.com/a/33428208/7767664 ¿por qué lo repitió?
user924
4

Si está utilizando la última versión l; .no tiene que agregar experimental = true.

en el nivel de proyecto Gradle

classpath 'org.jetbrains.kotlin:kotlin-gradle-plugin:1.3.21'

Y en el nivel de aplicación Gradle

apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions' //These should be on the top of file.

y en dependencias ..

implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.3.21'

e importar a continuación como

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

y ejemplo

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

class AnimalVH(parent: ViewGroup, layoutID: Int) : BaseViewHolder<Animal>(parent, layoutID) {

    override fun bindData(animal: Animal) {
        itemView.tv_animal.text = animal.title
    }
}

donde BaseViewHolder es

abstract class BaseViewHolder<T>(parent: ViewGroup, layoutID: Int) : RecyclerView.ViewHolder(
    LayoutInflater.from(parent.context).inflate(layoutID, parent, false)
) {
    abstract fun bindData(model: T)
}
AndroidGeek
fuente
¿Hay alguna confirmación oficial sobre esto? Creo que el uso de la .view.*importación anula el propósito, la alternativa será findViewById<>, cada vez, el mismo patrón del que a ViewHolderdisuadir.
Skynet
Explicado en: proandroiddev.com/…
Skynet
1

Significa que debe colocar esta línea al comienzo de su archivo fuente:

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

Así que ahora en lugar de, por ejemplo, findView(R.id.textView) as TextViewescribirías solo textView. Esta última es una propiedad de extensión sintética ubicada en el paquete kotlinx.android.synthetic.main.view, por eso tienes que importar todo desde él.

Hay un tutorial en el sitio oficial , échale un vistazo.

Alexander Udalov
fuente
1
Lo he visto todavía. Lo he hecho por mi actividad, como describí anteriormente. Pero, ¿cómo puedo usarlo dentro de los derivados de BaseAdapter?
Busylee
1
Bueno, básicamente puedes invocar un findViewById()método en View, como holder.findViewById(R.id.name). Con las extensiones de Kotlin para Android, puede escribir solo holder.name. Supongamos que este código está escrito dentro de una getView()función:val base = inflater.inflate(R.layout.list_item, parent, false) base.name.text = "John Smith"
yanex
Pero, ¿qué pasa si tengo que usar varios titulares de vista con varios diseños? ¿Cómo puedo realizarlo con sintético? Porque tenemos que usar un "enlace sintético" específico para cada diseño y tengo varios diseños con identificadores similares.
Natan Rubinstein
0

Para su información : se recomienda el enlace de datos en lugar de los sintéticos para las búsquedas de vistas.

Comentario de un DA para Android de Google en Reddit

¡Oye! ¡Abogado de desarrolladores para Android en Google aquí!

Quería agregar un poco de antecedentes aquí. Las extensiones de Kotlin con vistas sintéticas nunca fueron "recomendadas" intencionalmente, aunque eso no debe tomarse como una recomendación para no usarlas. Si funcionan para usted, no dude en seguir usándolos en su aplicación.

Nos hemos estado alejando de ellos (por ejemplo, no los enseñamos en el curso de Udacity) porque exponen un espacio de nombres global de identificadores que no está relacionado con el diseño que en realidad está inflado sin verificaciones contra búsquedas no válidas, son solo Kotlin y don no expone la posibilidad de nulos cuando las vistas solo están presentes en alguna configuración. En conjunto, estos problemas hacen que la API aumente el número de bloqueos de las aplicaciones de Android.

Por otro lado, ofrecen una API ligera que puede ayudar a simplificar las búsquedas de vistas. En este espacio, también vale la pena echar un vistazo a Data Binding, que también realiza búsquedas de vistas automáticas, además de integrarse con LiveData para actualizar automáticamente sus vistas a medida que cambian los datos.

Hoy, hay algunas opciones en este espacio que funcionan:

El enlace de datos es la recomendación para la búsqueda de vistas y el enlace, pero agrega un poco de sobrecarga en comparación con las extensiones de Android Kotlin. Vale la pena echarle un vistazo para ver si se ajusta bien a su aplicación. El enlace de datos también le permite observar LiveData para enlazar vistas automáticamente cuando cambian los datos. En comparación con Kotlin Extensions, agrega verificación de tiempo de compilación de búsquedas de vistas y seguridad de tipos. Las extensiones de Android Kotlin no se recomiendan oficialmente (lo que no es lo mismo que la recomendación en contra). Viene con los problemas mencionados anteriormente, por lo que para nuestro código no los estamos usando. Butter Knife es otra solución que es extremadamente popular y funciona tanto para Kotlin como para Java Programming Language. Leyendo los comentarios aquí allí ' Muchos desarrolladores están teniendo mucha suerte con Kotlin Extensions. Eso es genial, y algo que tendremos en cuenta al buscar formas de seguir mejorando nuestras API. Si no ha echado un vistazo a Data Binding, definitivamente inténtelo.

Por otro lado, nuestra guía de estilo de código interno no está diseñada para aplicarse directamente fuera de nuestra base de código. Por ejemplo, usamos mPrefixVariables, pero no hay ninguna razón por la que todas las aplicaciones deban seguir ese estilo.

usuario158
fuente