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
- Evite códigos estándar como:
val typedArray = view.context.theme.obtainStyledAttributes(...)
try {
radius = typedArray.getDimension(...)
// do more with typedArray...
} finally {
a.recycle()
}
- Haz que tus propiedades sean dinámicas usando el
dynamicAttr
extensión. Cuando se actualizan estas propiedades, la vista se actualiza automáticamente llamandorequestLayout()
Yinvalidate()
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
oprotected
.
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()
YrequestLayout()
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.
.