Encuadernación con vista de Android Kotlin: findViewById vs Butterknife vs Kotlin Android Extension

Estoy tratando de encontrar la mejor manera de hacer Android View Binding en Kotlin. Parece que hay algunas opciones disponibles:

findViewById

val button: Button by lazy { findViewById<Button>(R.id.button) } 

Cuchillo de mantequilla

https://github.com/JakeWharton/butterknife

 @BindView(R.id.button) lateinit var button: Button 

Extensiones de Kotlin para Android

https://kotlinlang.org/docs/tutorials/android-plugin.html

 import kotlinx.android.synthetic.main.activity_main.* 

Estoy bastante familiarizado con findViewById y Butterknife en Java, pero ¿cuáles son los pros y los contras de cada enfoque binding de vista en Kotlin?

¿Las extensiones de Kotlin para Android funcionan bien con el patrón RecyclerView + ViewHolder?

Además, ¿cómo maneja Kotlin Android Extensions el enlace de vista para vistas anidadas a través de include ?

ej .: para una actividad que usa activity_main.xml , ¿cómo se puede acceder a View custom1 ?

activity_main.xml

 <...> <include layout="@layout/custom" android:id="@+id/custom" /> </> 

custom.xml

 <...> <View android:id="@+id/custom1" ... /> <View android:id="@+id/custom2" ... /> </> 

No puedo marcar esta pregunta como un duplicado, ya que está preguntando varias cosas que han sido respondidas / discutidas bajo diferentes preguntas.

¿Cuáles son los pros y los contras de cada enfoque binding de vista en Kotlin?

Esto ha sido discutido aquí .

¿Cómo maneja Kotlin Android Extensions el enlace de vista para vistas anidadas a través de include? ej .: para una actividad que usa activity_main.xml, ¿cómo se puede acceder a View custom1?

Todas las extensiones de Kotlin para Android lo findViewById por findViewById . Mira aquí .

¿Las extensiones de Kotlin para Android funcionan bien con el patrón RecyclerView + ViewHolder?

Sí, lo hace. Sin embargo, debe save las Vistas que obtiene de las properties, ya que no hay caching para ellas como en Actividades o Fragmentos. Mira aquí .


Si aún tiene preguntas sin contestar, no dude en solicitar una aclaración.

kotlin-android-extensions es mejor para Kotlin . ButterKnife también es bueno, pero kotlin-android-extensions es una opción mejor e inteligente aquí.

Motivo : Kotlin usa properties synthetic y se llaman bajo demanda utilizando la caching function (por lo tanto, carga / actividad de rápido ligero) mientras ButterKnife une todas las vistas a la vez en ButterKnife.bind() (que consume un poco más de time). Con Kotlin ni siquiera necesita usar la anotación para enlazar las vistas.

Sí, también funciona bien con el patrón RecyclerView + ViewHolder, solo necesita importar kotlinx.android.synthetic.main.layout_main.view.* (Si layout_main.xml es el nombre de file de layout de actividad / fragment).

No necesita hacer ningún esfuerzo adicional para el layout importado mediante include . Solo use la identificación de las vistas importadas.

Eche un vistazo a las siguientes notas de documentation oficial:

Kotlin Android Extensions es un complemento para el comstackdor de Kotlin, y hace dos cosas:

  1. Agrega una function de almacenamiento en caching oculta y un campo dentro de cada actividad de Kotlin. El método es bastante pequeño, por lo que no aumenta mucho el tamaño de APK.
  2. Reemplaza cada llamada de propiedad sintética con una llamada de function.

    Cómo funciona esto es que cuando se invoca una propiedad sintética, donde el receptor es una class de Actividad / Fragmento de Kotlin que está en fonts de modules, se invoca la function de almacenamiento en caching. Por ejemplo, dado

 class MyActivity : Activity() fun MyActivity.a() { this.textView.setText(“”) } 

se genera una function de almacenamiento en caching oculta dentro de MyActivity, por lo que podemos utilizar el mecanismo de almacenamiento en caching.

Sin embargo, en el siguiente caso:

 fun Activity.b() { this.textView.setText(“”) } 

No sabríamos si esta function se invocaría solo en Actividades de nuestras fonts o también en Actividades Java simples. Como tal, no usamos el almacenamiento en caching allí, incluso si la instancia de MyActivity del ejemplo anterior es el receptor.

Enlace a la página de documentation anterior

Espero que ayude.

Cuida de usar

 val button: Button by lazy { findViewById<Button>(R.id.button) } 

Ya me enfrento al problema cuando se destruye la vista, y como la instancia de su fragment sobrevive (creo que en el caso de las actividades no se aplica), tienen la propiedad perezosa haciendo reference a la vista anterior.

Ejemplo:

Tiene un valor estático en el layout, digamos android:text="foo"

 //calling first time override fun onViewCreated(view: View?, savedInstanceState: Bundle?) { button.setText("bar") // button is called for the first time, // then button is the view created recently and shows "bar" } 

Luego, el fragment se destruye porque lo reemplazas, pero luego vuelves y se vuelve a generar la invocación en Crear nuevamente.

 //calling second after destroyed override fun onViewCreated(view: View?, savedInstanceState: Bundle?) { button.setText(Date().time.toString()) //button is already set, then you are setting the value the to old view reference // and in your new button the value won't be assigned // The text showed in the button will be "foo" } 
  • ¿Cómo conseguir ARTE ALBUM de una canción de su path en kotlin?
  • Hacer reference a las vistas con la misma identificación en diferentes layouts con extensiones de android kotlin
  • Error: ejecución fallida para la tarea ': aplicación: limpiar'. No se puede borrar el file
  • Extensión sintética Kotlin para ver
  • Usar las extensiones de resources de Kotlin para Android usando solo Maven
  • Extensiones de Kotlin / properties sintéticas: mismo object en múltiples invocaciones de Fragment.onViewCreated ()
  • Cambiar el filter de color del elemento del cajón de navigation también cambia el imageView, que es el mismo ID de image
  • La propiedad en la interfaz no puede tener un campo de respaldo
  • Cómo lanzar Cadena en Int y Largo?
  • No se pudo encontrar la class 'kotlin.jvm.internal.DefaultConstructorMarker'
  • Android Kotlin - Volley Código de respuesta inesperada 400