Android-Datenbindung mit einer benutzerdefinierten Ansicht

Die AndroidDatenbindungs-Anleitung erörtert verbindliche Werte innerhalb einer Aktivität oder eines Fragments, aber gibt es eine Möglichkeit, die Datenbindung mit einer benutzerdefinierten Ansicht durchzuführen?

Ich möchte so etwas wie:

  • Verständnis Android's Webview addjavascriptinterface
  • Wie man Ansichten auf ein ImageView stellt, in Bezug auf die Imagegröße des ImageViews?
  • Retrofit 2 und RxJava Fehlerbehandlung Betreiber
  • Wie man Margin zu einem Button zur Laufzeit hinzufügen?
  • Android - Kommunikation zwischen zwei Geräten
  • Android-benutzerdefinierte ListView kann nicht auf Elemente klicken
  • <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> 

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

    Während es möglich ist, dies zu tun, indem Sie benutzerdefinierte Attribute auf die benutzerdefinierte Ansicht setzen, würde dies schnell umständlich, wenn es viele Werte zu binden.

    Gibt es einen guten Weg, um zu erreichen, was ich versuche zu tun?

  • Android benutzerdefinierte Build mit Ant
  • FloatingActionButton Beispiel mit Support Library
  • FFMPEG schob RTMP Stream nicht auf Android und iPhone
  • Android-Check-Berechtigung für LocationManager
  • Delphi XE5 Serieller Port auf Android
  • Wie zu beheben: Fehler-Gerät nicht mit ADB.exe gefunden
  • 3 Solutions collect form web for “Android-Datenbindung mit einer benutzerdefinierten Ansicht”

    In deiner benutzerdefinierten Ansicht aufblasen Sie das Layout, aber Sie würden normalerweise einen Setter für das Attribut setzen, das Sie setzen möchten:

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

    Dann in das Layout verwenden Sie es in:

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

    Im obigen wird ein automatisches Bindungsattribut für app: myViewModel erstellt, da es einen Setter mit dem Namen setMyViewModel gibt.

    Erstens tun dies nicht, wenn diese benutzerdefinierte Ansicht bereits <include> in einem anderen Layout, wie zB Aktivität etc. ist. Sie erhalten nur eine Ausnahme über das Tag ist unerwarteter Wert. Die Datenbindung lief bereits die Bindung an sie, also bist du eingestellt.

    Haben Sie versucht, onFinishInflate zu verwenden, um die Bindung auszuführen? (Kotlin Beispiel)

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

    Denken Sie daran, dass, wenn Sie die Bindung in Ihrer Ansicht verwenden, wird es nicht in der Lage, programmgesteuert erstellt werden, zumindest wäre es sehr gewellt, um beide zu unterstützen, auch wenn Sie können.

    Nach der von george präsentierten Lösung konnte der grafische Editor im Android-Studio nicht mehr in der Lage sein, die benutzerdefinierte Ansicht zu machen. Der Grund dafür ist, dass keine Ansicht tatsächlich in den folgenden Code aufgeblasen ist:

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

    Ich nehme an, dass die Bindung die Inflation behandelt, aber der grafische Herausgeber hat es nicht gefallen.

    In meinem speziellen Anwendungsfall wollte ich ein einziges Feld binden und kein ganzes Ansichtsmodell. Ich kam mit (kotlin eingehenden):

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

    Die ähnliche Schaltfläche besteht aus einem Bild und einer Textansicht. Die Textansicht enthält die Anzahl der Vorlieben, die ich über die Datenbindung festlegen möchte.

    Durch die Verwendung des Setzers für numberOfLikes als Attribut in der folgenden xml, Datenbindung automatisch macht die Vereinigung:

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

    Weiterführende Literatur: https://medium.com/google-developers/android-data-binding-custom-setters-55a25a7aea47

    Das Android ist ein Google Android Fan-Website, Alles ├╝ber Android Phones, Android Wear, Android Dev und Android Spiele Apps und so weiter.