Привязка данных Android к пользовательскому представлению

В руководстве по привязке данных Android обсуждаются значения привязки в рамках действия или фрагмента, но есть ли способ выполнить привязку данных к пользовательскому виду?

Я хотел бы сделать что-то вроде:

<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> 

С 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> 

Хотя представляется возможным сделать это, установив пользовательские атрибуты в пользовательском представлении, это быстро станет громоздким, если есть много значений для привязки.

Есть ли хороший способ сделать то, что я пытаюсь сделать?

Solutions Collecting From Web of "Привязка данных Android к пользовательскому представлению"

В своем пользовательском представлении раздуйте макет, но вы, как правило, будете и установите установщик для атрибута, который вы хотите установить:

 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); } 

Затем в макете вы используете ее в:

 <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> 

В вышесказанном, атрибут автоматической привязки создается для приложения: myViewModel, потому что есть сеттер с именем setMyViewModel.

Во-первых, не делайте этого, если этот пользовательский вид уже является <include> в другом макете, таком как активность и т. Д. Вы просто получите исключение из-за неожиданного значения тега. Связывание данных уже выполнило привязку на нем, поэтому вы настроены.

Вы пытались использовать onFinishInflate для запуска привязки? (Пример Котлина)

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

Имейте в виду, что если вы используете привязку в своем представлении, она не сможет быть создана программно, по крайней мере, она будет очень запутанной, чтобы поддерживать обе, даже если вы можете.

После решения, представленного Джорджем, графический редактор в студии Android больше не смог отобразить пользовательский вид. Причина в том, что в следующем коде фактически не раздувается представление:

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

Я полагаю, что привязка обрабатывает инфляцию, однако графическому редактору это не понравилось.

В моем конкретном случае использования я хотел связать одно поле, а не всю модель представления. Я придумал (kotlin входящий):

 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() } } 

Подобная кнопка состоит из изображения и текстового вида. В текстовом представлении указано количество симпатий, которые я хочу установить с помощью привязки данных.

Используя setter для numberOfLikes как атрибут в следующем xml, привязка данных автоматически делает ассоциацию:

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

Дальнейшее чтение: https://medium.com/google-developers/android-data-binding-custom-setters-55a25a7aea47