Join FlipAndroid.COM Telegram Group: https://t.me/joinchat/F_aqThGkhwcLzmI49vKAiw


Vinculación de datos android con una vista personalizada

La guía de vinculación de datos de Android discute valores vinculantes dentro de una actividad o fragmento, pero ¿existe una manera de realizar vinculación de datos con una vista personalizada?

Me gustaría hacer algo como:

<LinearLayout android:layout_width="match_parent" android:layout_height="match_parent"> <com.mypath.MyCustomView android:id="@+id/my_view" android:layout_width="match_parent" android:layout_height="40dp"/> </LinearLayout> 

Con my_custom_view.xml :

 <layout> <data> <variable name="myViewModel" type="com.mypath.MyViewModelObject" /> </data> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@{myViewModel.myText}" /> </LinearLayout> </layout> 

Aunque parece posible hacerlo mediante la configuración de atributos personalizados en la vista personalizada, esto se convertiría rápidamente en engorroso si hay una gran cantidad de valores para enlazar.

¿Hay una buena manera de lograr lo que estoy tratando de hacer?

  • Vista personalizada Ampliación del diseño relativo
  • Android: vista personalizada basada en el diseño: ¿cómo?
  • Constructor de vista personalizada de Android
  • Android - ¿Es posible crear una biblioteca personalizada para usarla en varias aplicaciones?
  • ¿Buenas prácticas para hacer frente al costoso cálculo de la altura de la vista?
  • 3 Solutions collect form web for “Vinculación de datos android con una vista personalizada”

    En su vista personalizada, infle el diseño como lo haría normalmente y proporcionará un setter para el atributo que desea establecer:

     private MyCustomViewBinding mBinding; public MyCustomView(...) { ... LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); mBinding = MyCustomViewBinding.inflate(inflater); } public void setMyViewModel(MyViewModelObject obj) { mBinding.setMyViewModel(obj); } 

    A continuación, en el diseño que se utiliza en:

     <layout xmlns...> <data> <variable name="myViewModel" type="com.mypath.MyViewModelObject" /> </data> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent"> <com.mypath.MyCustomView android:id="@+id/my_view" app:myViewModel="@{myViewModel}" android:layout_width="match_parent" android:layout_height="40dp"/> </LinearLayout> </layout> 

    En lo anterior, se crea un atributo de enlace automático para app: myViewModel porque hay un setter con el nombre setMyViewModel.

    En primer lugar, no haga esto si esta vista personalizada ya está siendo <include> en otro diseño, como actividad, etc. Sólo obtendrá una excepción acerca de que la etiqueta sea un valor inesperado. El enlace de datos ya corría el enlace en él, por lo que está configurado.

    ¿Intentaste usar onFinishInflate para ejecutar el enlace? (Ejemplo Kotlin)

     override fun onFinishInflate() { super.onFinishInflate() this.dataBinding = MyCustomBinding.bind(this) } 

    Tenga en cuenta que si utiliza el enlace en su vista, no se podrá crear de forma programática, al menos sería muy complicado para apoyar a ambos, incluso si se puede.

    Siguiendo la solución presentada por george el editor gráfico en android studio ya no era capaz de hacer la vista personalizada. La razón es que ninguna vista se infla realmente en el código siguiente:

     public MyCustomView(...) { ... LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); mBinding = MyCustomViewBinding.inflate(inflater); } 

    Supongo que el encuadre se encarga de la inflación, sin embargo, el editor gráfico no le gusta.

    En mi caso de uso específico quería unir un solo campo y no un modelo de vista completo. Vine con (kotlin entrante):

     class LikeButton @JvmOverloads constructor( context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0 ) : ConstraintLayout(context, attrs, defStyleAttr) { val layout: ConstraintLayout = LayoutInflater.from(context).inflate(R.layout.like_button, this, true) as ConstraintLayout var numberOfLikes: Int = 0 set(value) { field = value layout.number_of_likes_tv.text = numberOfLikes.toString() } } 

    El botón similar consiste en una imagen y una vista de texto. La vista de texto contiene el número de gustos, que quiero establecer mediante enlace de datos.

    Al usar el setter para numberOfLikes como un atributo en el xml siguiente, el enlace de datos automáticamente hace que la asociación:

     <views.LikeButton android:id="@+id/like_btn" android:layout_width="wrap_content" android:layout_height="wrap_content" app:numberOfLikes="@{story.numberOfLikes}" /> 

    Más información: https://medium.com/google-developers/android-data-binding-custom-setters-55a25a7aea47

    FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.