Emad Razavi
View Binding se lanzó como parte de Android Jetpack
Documentos: https://developer.android.com/topic/libraries/view-binding
Mi pregunta es cómo usar el enlace de vista con vistas personalizadas. La documentación de Google solo muestra Actividad y fragmento.
Intenté esto, pero no se mostró nada.
LayoutInflater inflater = LayoutInflater.from(getContext());
Y luego, usé este, pero de nuevo, sin suerte.
LayoutInflater inflater = (LayoutInflater)
getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
Supongo que tal vez no apunte al inflador de diseño correcto para mi vista, pero no estoy seguro.
Androiderson
Solo informe a la raíz y si desea adjuntarla
init { // inflate binding and add as view
binding = ResultProfileBinding.inflate(LayoutInflater.from(context), this)
}
o
init { // inflate binding and add as view
binding = ResultProfileBinding.inflate(LayoutInflater.from(context), this, true)
}
qué método de inflado usar dependerá del tipo de diseño raíz en xml.
-
¿Qué hay de inflar la vista del recurso de diseño existente? Me gusta
init { inflate(context, R.layout.my_view, this) }
?– anticafé
8 de junio de 2020 a las 1:56
-
¿Debo establecer el
binding
variable anull
en algún lugar, similar a cómo deben implementarse en fragmentos?– Emilio S.
11 de febrero de 2021 a las 16:46
-
¿Necesitamos establecer la referencia en nulo en alguna parte?
-Gordon Tseng
16 de febrero de 2021 a las 22:47
-
NO establezca los enlaces en nulo. No hay necesidad. Un Fragmento puede sobrevivir a la destrucción de su vista. Una vista personalizada no puede.
– Nino DELCEY
6 abr a las 14:54
-
No es necesario establecer el enlace en nulo en las vistas, solo en Fragmentos. developer.android.com/topic/libraries/view-binding#fragments
-Den Drobiazko
11 abr a las 10:49
Pavneet_Singh
Para usar el enlace de vista, debe usar la clase de enlace generada, no el LayoutInflater
por ejemplo, si el nombre del diseño es result_profile.xml
entonces necesitas usar ResultProfileBinding
como:
class CustomView @kotlin.jvm.JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : FrameLayout(context, attrs, defStyleAttr) {
private lateinit var binding: ResultProfileBinding
init { // inflate binding and add as view
binding = ResultProfileBinding.inflate(LayoutInflater.from(context))
addView(binding.root)
}
}
- Clase generada automáticamente:
result_profile.xml
->ResultProfileBinding
(nombre del diseño, adjunto conBinding
) -
Inflar la unión
ResultProfileBinding.inflate(LayoutInflater.from(context))
-
Usar
addView
para agregar la vista en la jerarquía como:addView(binding.root)
Nota: Si se extiende desde ConstraintLayout
(es la clase principal) luego use el conjunto de restricciones
-
Gracias. Su respuesta puede ser útil en algunas partes, pero necesito una forma de usar el enlace de vista para inflar con la vista raíz sin agregar la vista a la vista raíz.
–Emad Razavi
27 de febrero de 2020 a las 13:08
-
@EmiRaz si se crea su vista personalizada (java/kotlin), agregue su vista personalizada en el diseño XML y luego puede acceder directamente a su vista personalizada desde el
binding
objeto comobinding.customview
o si desea usar el enlace de vista como suena (how to use view binding with custom views
) luego siga la respuesta. para su información:inflater
se usa para inflar nuevas vistas usando los diseños xml– Pavneet_Singh
27 de febrero de 2020 a las 13:17
-
Si infla la vista en el bloque de inicio (como pregunta @EmiRaz), simplemente termina en un bucle infinito donde la inflación vuelve a llamar al bloque de inicio. Él está preguntando cómo usar
CustomViewBinding
dentro deCustomView
– Jason Toms
27 de febrero de 2020 a las 13:22
-
@Downvoter: ¿puedo saber el motivo del voto negativo? ya que claramente agregué los detalles sobre cómo usar la vista personalizada con enlace de vista y agregué los detalles faltantes en el OP en los comentarios
– Pavneet_Singh
27 de febrero de 2020 a las 13:22
-
@JasonToms, ¿por qué crearía un bucle? ¿Lo has probado? ya que usaremos la clase de enlace generada del diseño en nuestra vista personalizada
– Pavneet_Singh
27 de febrero de 2020 a las 13:26
levon petrosyan
Puede inicializar la propiedad de enlace de vista de inmediato
private val binding = CustomViewBinding.inflate(LayoutInflater.from(context), this)
-
¿Puede ser perezoso?
– Amigo Kanchan
1 de septiembre de 2021 a las 18:08
-
Puede, pero creo que, a menos que esté haciendo un enlace pesado, no debe hacerlo perezoso, ya que conlleva una sobrecarga adicional.
– Levon Petrosián
1 sep 2021 a las 20:07
-
No puede si su CustomView tiene como raíz un ConstraintLayout
– Skizo-ozᴉʞS
18 de noviembre de 2021 a las 16:26
jason toms
Si está tratando de usar View Binding con la vista raíz, esto funciona para mí:
class CustomView @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : ConstraintLayout(context, attrs, defStyleAttr) {
private lateinit var binding: CustomViewBinding
override fun onFinishInflate() {
super.onFinishInflate()
binding = CustomViewBinding.bind(this)
}
}
Esta es la respuesta de Kotlin más simple que se me ocurre. Es una vista personalizada que simplemente envuelve un solo TextView y proporciona un update(s:String)
Función para actualizar el texto.
<!-- view_stub.xml -->
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<TextView android:id="@+id/myTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</layout>
// StubView.kt
class StubView @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : FrameLayout(context,attrs,defStyleAttr) {
val binding = ViewStubBinding.inflate(context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater)
.also { addView(it.root) }
fun update(updatedText: String) {
binding.myTextView.text = updatedText
}
}
Las dos cosas que me gustan de esta respuesta son:
binding
es unval
en lugar de unvar
. Intento limitar el número devar
s tanto como sea posible.- los
addView
está íntimamente relacionado con laval binding
utilizando elalso {}
función de alcance en lugar de unainit {}
cláusula, haciendo que la instanciación de laView
sentirse mucho más declarativo.
Se podría argumentar que el addView()
es realmente un efecto secundario y debe estar en el init {}
sección para que sea independiente de la declaración de la binding
valor Yo diría lo contrario: declarar un val
luego alimentarlo a una sección de código que lo necesita no me parece un efecto secundario.
-
¿Por qué no simplemente
attachToParent=true
eninflate()
? Debería ser equivalente.– Jinete del viento
17 de diciembre de 2020 a las 13:38
-
¿Por qué no simplemente
attachToParent=true
eninflate()
? Debería ser equivalente.– Jinete del viento
17 de diciembre de 2020 a las 13:38
Consulte los adaptadores de unión: desarrollador.android.com/topic/libraries/data-binding/…
– Guerrero Ruthwik
27 de febrero de 2020 a las 12:47
@RuthwikWarrier ¿Podría dar más detalles? porque estoy preguntando sobre el enlace de vista, no el enlace de datos.
–Emad Razavi
27 de febrero de 2020 a las 12:50
Hay una pregunta similar con una respuesta válida: stackoverflow.com/a/60425755/7339798
– Volodymyr Buberenko
30 de marzo de 2020 a las 19:14
@RuthwikWarrier, lamento no estar de acuerdo, pero la pregunta es sobre el enlace de vista desarrollador.android.com/topic/libraries/view-binding en lugar de enlace de datos como enlace proporcionado por usted
– peter_budo
13 de diciembre de 2020 a las 16:22