El arsenal de Android – Enlace de datos

cuchara de mesa (del nombre creativo de Dagger and Butterknife) lo ayuda a asociar fácilmente atributos en sus vistas personalizadas mediante anotaciones para generar código estándar.

class CustomView (...) : View(...) {

  @ColorAttr(R.styleable.CustomView_bgColor)
  var bgColor: Int = Color.RED

  @DimensionAttr(R.styleable.CustomView_radius)
  var radius: Float = 0f

  var text: String by dynamicAttr("") // Auto updates View when being set

  init {
    TableSpoon.init(this, attrs, R.styleable.CustomView)
  }
}

Características

  1. Evite códigos estándar como:
val typedArray = view.context.theme.obtainStyledAttributes(...)
try {
  radius = typedArray.getDimension(...)
  // do more with typedArray...
} finally {
  a.recycle()
}
  1. Haz que tus propiedades sean dinámicas usando el dynamicAttr extensión. Cuando se actualizan estas propiedades, la vista se actualiza automáticamente llamando requestLayout() Y invalidate() en la vista

Instalar

Puede instalar Tablespoon agregando esto a su archivo build.gradle:

dependencies {
    implementation 'com.nikhilpanju:tablespoon:1.0.2'
    kapt 'com.nikhilpanju:tablespoon-processor:1.0.2'
}

Limitación

Desde Android Gradle Plugin 5.0 en adelante (aún por lanzar), los ID de recursos (cualquier R.xyz valor) no será definitiva. Para evitar esto, agregue Complemento de Gradle Butterknife para usted buildscript.

buildscript {
  repositories {
    mavenCentral()
  }
  dependencies {
    classpath 'com.jakewharton:butterknife-gradle-plugin:10.1.0'
  }
}

y luego aplicarlo en su forma:

apply plugin: 'com.android.library'
apply plugin: 'com.jakewharton.butterknife'

Ahora asegúrese de usar R2 en lugar de R dentro de todas las anotaciones de cucharada:

@ColorAttr(R2.styleable.CustomView_bgColor)
var bgColor: Int = Color.RED

Uso

En primer lugar, todos los atributos deben declararse en res/values/attrs.xml. Por ejemplo:

<resources>
  <declare-styleable name="CustomView">
    <attr name="bgColor" format="color" />
    <attr name="radius" format="dimension" />
    <attr name="icon" format="reference" />
  </declare-styleable>
</resources>

Cada uno de estos atributos se puede utilizar con la anotación respectiva.

  • Todas las anotaciones deben definirse con el ID de atributo correspondiente como se definió anteriormente.
  • Tablespoon.init() debe llamarse en el constructor de vistas con el ID de estilo principal como se definió anteriormente (R.styleable.CustomView)
  • Los valores predeterminados se pueden definir directamente en la propiedad
  • Las propiedades no pueden ser private o protected.

Ejemplo

class CustomView @JvmOverloads constructor(
  context: Context,
  attrs: AttributeSet? = null
) : View(context, attrs, defStyleAttr) {

  @ColorAttr(R.styleable.CustomView_bgColor)
  var bgColor: Int = Color.RED // RED is default value

  @DimensionAttr(R.styleable.CustomView_radius)
  var radius: Float = 0f // 0f is default value

  // dynamic attributes auto update your view when they are updated
  @delegate:DrawableAttr(R.styleable.CustomView_icon)
  var icon: Drawable? by dynamicDrawableAttr(null)

  init {
    TableSpoon.init(this, attrs, R.styleable.CustomView)
  }
}

Inicialización

Tablespoon.init() se puede llamar utilizando todos o algunos de los parámetros del constructor de vistas. Además, también puede proporcionar una lambda que se llamará TypedArray antes de reciclarlo en caso de que necesite realizar algunas operaciones personalizadas.

class CustomView @JvmOverloads constructor(
  context: Context,
  attrs: AttributeSet? = null,
  defStyleAttr: Int = 0,
  defStyleRes: Int = 0,
) : View(context, attrs, defStyleAttr, defStyleRes) {

  var fullName: String? = null

  init {
    TableSpoon.init(this, attrs, R.styleable.CustomView, defStyleAttr, defStyleRes) {
      // this block is called using: TypedArray.() -> Unit

      fullName = getString(R.styleable.CustomView_firstName) +
        getString(R.styleable.CustomView_lastName)

      // ... any other operation on TypedArray before it's recycled
    }
  }
}

Propiedades dinámicas

Estas son propiedades que volverán a dibujar automáticamente la vista cuando se actualicen.

@delegate:ColorAttr(R.styleable.CustomView_bgColor)
var bgColor: Int by dynamicIntAttr(Color.RED) // RED is default value

fun makeBgGreen() {
  // updating bgColor here will automatically update the view by
  // calling the view's requestLayout and invalidate methods
  bgColor = Color.GREEN
}

Nota: Cuando se usan propiedades dinámicas anotadas, el prefijo @delegate: debe usarse antes de la anotación para que se pueda orientar al delegado.

  • Para cualquier propiedad que no esté anotada, puede usar dynamicAttr().

Parámetros adicionales

  • Si tu no quieres ambos invalidate() Y requestLayout() para ser llamado, puede establecer uno en falso.
  • También puede proporcionar un lambda que se llamará antes de actualizar la vista (actúa como un Observable delegar).
var stringAttr: String by dynamicStringAttr(
  initialValue = "default string",
  invalidate = true, // default is true
  requestLayout = false // default is true
) { newString ->
  // this block is called before the view is updated
  // in case some pre-operations need to be performed
}

Propiedades dinámicas y anotaciones

A continuación se muestra una lista de todos los posibles delegados de propiedades dinámicas y anotaciones que se pueden usar para cada atributo y tipo de campo.

Tipo de atributo XML Tipo de campo Anotación Delegado de propiedad dinámica
booleano booleano @BooleanAttr BooleanAttr dinámico ()
color En t @ColorAttr dynamicIntAttr ()
color ColorStateListColorStateList @ColorAttr DynamicColorStateAttr ()
dimensión En t @DimensionAttr dynamicIntAttr ()
dimensión Flotante @DimensionAttr FloatAttr dinámico ()
enumeración En t @IntAttr dynamicIntAttr ()
banderas En t @IntAttr dynamicIntAttr ()
flotante Flotante @FloatAttr FloatAttr dinámico ()
número entero En t @IntAttr dynamicIntAttr ()
referencia En t @ResourceIdAttr dynamicIntAttr ()
referencia Dibujable @DrawableAttr atributoDrawableAttr dinámico ()
soga Soga @StringAttr atributo de cadena dinámica ()

DrawableAttr

@DrawableAttr es un registro de conveniencia para llegar directamente Drawable de una referencia / ID de recurso. dynamicDrawableAttr() es el delegado correspondiente de la propiedad dinámica.

Contribuir

¡Las solicitudes de extracción son bienvenidas! Siéntase libre de buscar problemas abiertos para cosas que necesitan trabajo. Si tiene una solicitud de función o un error, abra un nuevo problema para que podamos rastrearlo.

Licencia

Copyright 2020 Nikhil Panju.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

.

Compruebe también

en vivo desde Droidcon, incluida la mayor actualización de Gemini en Android Studio y más lanzamientos del SDK de Android.

Acabamos de lanzar nuestro episodio de otoño de #TheAndroidShow en YouTube etcétera desarrollador.android.comy esta vez …

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *