Değerleri ayarlamak için uygun çerçeve çağrıları yapmaktan bağdaştırıcıları bağlama sorumluluğu vardır. Örnek olarak, setText()
yöntemini çağırmak gibi bir özellik değeri belirlemek verilebilir. Diğer bir örnek de setOnClickListener()
yöntemini çağırmak gibi bir etkinlik işleyici ayarlamaktır.
Veri Bağlama Kitaplığı, bir değer ayarlamak için çağrılan yöntemi belirtmenize, kendi bağlama mantığınızı sağlamanıza ve bağdaştırıcıları kullanarak döndürülen nesnenin türünü belirtmenize olanak tanır.
Özellik değerlerini ayarlama
Bir bağlı değer değiştiğinde, oluşturulan bağlama sınıfı, görünümde bağlama ifadesiyle bir setter yöntemini çağırmalıdır. Veri Bağlama Kitaplığı'nın yöntemi otomatik olarak belirlemesine izin verebilir veya yöntemi açıkça beyan edebilir ya da yöntem seçmek için özel mantık sağlayabilirsiniz.
Otomatik yöntem seçimi
Kitaplık, example
adlı bir özellik için uyumlu türleri bağımsız değişken olarak kabul eden setExample(arg)
yöntemini otomatik olarak bulur. Özelliğin ad alanı dikkate alınmaz. Yöntem aranırken yalnızca özellik adı ve türü kullanılır.
Örneğin, android:text="@{user.name}"
ifadesiyle kitaplık, user.getName()
tarafından döndürülen türü kabul eden bir setText(arg)
yöntemi arar. user.getName()
dönüş türü String
ise kitaplık, String
bağımsız değişkenini kabul eden bir setText()
yöntemi arar. İfade bir int
döndürürse kitaplık, int
bağımsız değişkenini kabul eden bir setText()
yöntemini arar. İfade doğru türü döndürmelidir. Gerekirse döndürülen değeri yayınlayabilirsiniz.
Verilen ada sahip herhangi bir özellik bulunmasa bile veri bağlama çalışır. Veri bağlama özelliğini kullanarak herhangi bir setter için özellik oluşturabilirsiniz. Örneğin, DrawerLayout
destek sınıfının özellikleri yoktur ama çok sayıda belirleyici vardır. Aşağıdaki düzen, app:scrimColor
ve app:drawerListener
özellikleri için ayarlayıcı olarak sırasıyla setScrimColor(int)
ve addDrawerListener(DrawerListener)
yöntemlerini otomatik olarak kullanır:
<androidx.drawerlayout.widget.DrawerLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:scrimColor="@{@color/scrim}"
app:drawerListener="@{fragment.drawerListener}">
Özel bir yöntem adı belirtin
Bazı özelliklerde ada göre eşleşmeyen ayarlayıcılar var. Bu durumlarda, BindingMethods
notasyonu kullanılarak bir özellik belirleyici ile ilişkilendirilebilir. Ek açıklama bir sınıfla kullanılır ve yeniden adlandırılmış her yöntem için bir tane olmak üzere birden fazla BindingMethod
ek açıklaması içerebilir. Bağlama yöntemleri, uygulamanızdaki her sınıfa ekleyebileceğiniz
ek açıklamalardır.
Aşağıdaki örnekte android:tint
özelliği, setTint()
yöntemiyle değil setImageTintList(ColorStateList)
yöntemiyle ilişkilendirilmiş:
Kotlin
@BindingMethods(value = [ BindingMethod( type = android.widget.ImageView::class, attribute = "android:tint", method = "setImageTintList")])
Java
@BindingMethods({ @BindingMethod(type = "android.widget.ImageView", attribute = "android:tint", method = "setImageTintList"), })
Genellikle Android çerçeve sınıflarında ayarlayıcıları yeniden adlandırmanız gerekmez. Özellikler, eşleştirme yöntemlerini otomatik olarak bulmak için ad kuralı kullanılarak halihazırda uygulanmıştır.
Özel mantık sağlayın
Bazı özellikler için özel bağlama mantığı gerekir. Örneğin, android:paddingLeft
özelliği için ilişkili bir ayarlayıcı yoktur. Bunun yerine setPadding(left,
top, right, bottom)
yöntemi sağlanır. BindingAdapter
notlu statik bağlama bağdaştırıcısı yöntemi, bir özellik için ayarlayıcının nasıl çağrılacağını özelleştirmenize olanak tanır.
Android çerçeve sınıflarının özellikleri zaten BindingAdapter
notlarına sahiptir. Aşağıdaki örnekte paddingLeft
özelliği için bağlama bağdaştırıcısı gösterilmektedir:
Kotlin
@BindingAdapter("android:paddingLeft") fun setPaddingLeft(view: View, padding: Int) { view.setPadding(padding, view.getPaddingTop(), view.getPaddingRight(), view.getPaddingBottom()) }
Java
@BindingAdapter("android:paddingLeft") public static void setPaddingLeft(View view, int padding) { view.setPadding(padding, view.getPaddingTop(), view.getPaddingRight(), view.getPaddingBottom()); }
Parametre türleri önemlidir. İlk parametre, özellikle ilişkilendirilmiş görünümün türünü belirler. İkinci parametre, belirtilen özelliğin bağlama ifadesinde kabul edilen türü belirler.
Adaptörleri bağlamak, diğer özelleştirme türleri için de yararlı olur. Örneğin, özel yükleyici bir resim yüklemek için bir çalışan iş parçacığından çağrılabilir.
Aşağıdaki örnekte gösterildiği gibi, birden çok özellik alan bağdaştırıcılarınız da olabilir:
Kotlin
@BindingAdapter("imageUrl", "error") fun loadImage(view: ImageView, url: String, error: Drawable) { Picasso.get().load(url).error(error).into(view) }
Java
@BindingAdapter({"imageUrl", "error"}) public static void loadImage(ImageView view, String url, Drawable error) { Picasso.get().load(url).error(error).into(view); }
Bağdaştırıcıyı düzeninizde, aşağıdaki örnekte gösterildiği gibi kullanabilirsiniz. @drawable/venueError
öğesinin, uygulamanızdaki bir kaynağı ifade ettiğini unutmayın. Kaynağın @{}
içine alınması, geçerli bir bağlama ifadesi olmasını sağlar.
<ImageView app:imageUrl="@{venue.imageUrl}" app:error="@{@drawable/venueError}" />
ImageView
nesnesi için imageUrl
ve error
kullanılıyorsa imageUrl
dize, error
ise Drawable
ise bağdaştırıcı çağrılır. Özelliklerden herhangi biri ayarlandığında bağdaştırıcının çağrılmasını istiyorsanız bağdaştırıcının isteğe bağlı requireAll
işaretini aşağıdaki örnekte gösterildiği gibi false
olarak ayarlayın:
Kotlin
@BindingAdapter(value = ["imageUrl", "placeholder"], requireAll = false) fun setImageUrl(imageView: ImageView, url: String?, placeHolder: Drawable?) { if (url == null) { imageView.setImageDrawable(placeholder); } else { MyImageLoader.loadInto(imageView, url, placeholder); } }
Java
@BindingAdapter(value={"imageUrl", "placeholder"}, requireAll=false) public static void setImageUrl(ImageView imageView, String url, Drawable placeHolder) { if (url == null) { imageView.setImageDrawable(placeholder); } else { MyImageLoader.loadInto(imageView, url, placeholder); } }
Bağdaştırıcı yöntemleri bağlama, işleyicilerindeki eski değerleri alabilir. Eski ve yeni değerler alan bir yöntemde önce özellikler için tüm eski değerler bildirilmelidir, ardından aşağıdaki örnekte gösterildiği gibi yeni değerler belirtilmelidir:
Kotlin
@BindingAdapter("android:paddingLeft") fun setPaddingLeft(view: View, oldPadding: Int, newPadding: Int) { if (oldPadding != newPadding) { view.setPadding(newPadding, view.getPaddingTop(), view.getPaddingRight(), view.getPaddingBottom()) } }
Java
@BindingAdapter("android:paddingLeft") public static void setPaddingLeft(View view, int oldPadding, int newPadding) { if (oldPadding != newPadding) { view.setPadding(newPadding, view.getPaddingTop(), view.getPaddingRight(), view.getPaddingBottom()); } }
Etkinlik işleyiciler, aşağıdaki örnekte gösterildiği gibi yalnızca tek bir soyut yöntem içeren arayüzlerle veya soyut sınıflarla kullanılabilir:
Kotlin
@BindingAdapter("android:onLayoutChange") fun setOnLayoutChangeListener( view: View, oldValue: View.OnLayoutChangeListener?, newValue: View.OnLayoutChangeListener? ) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { if (oldValue != null) { view.removeOnLayoutChangeListener(oldValue) } if (newValue != null) { view.addOnLayoutChangeListener(newValue) } } }
Java
@BindingAdapter("android:onLayoutChange") public static void setOnLayoutChangeListener(View view, View.OnLayoutChangeListener oldValue, View.OnLayoutChangeListener newValue) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { if (oldValue != null) { view.removeOnLayoutChangeListener(oldValue); } if (newValue != null) { view.addOnLayoutChangeListener(newValue); } } }
Bu etkinlik işleyiciyi düzeninizde aşağıdaki gibi kullanın:
<View android:onLayoutChange="@{() -> handler.layoutChanged()}"/>
Bir dinleyicinin birden fazla yöntemi varsa birden çok dinleyiciye bölünmelidir.
Örneğin, View.OnAttachStateChangeListener
iki yönteme sahiptir:
onViewAttachedToWindow(View)
ve
onViewDetachedFromWindow(View)
.
Kitaplık, özellikleri ve işleyicileri ayırt edebilmeniz için iki arayüz sağlar:
Kotlin
// Translation from provided interfaces in Java: @TargetApi(Build.VERSION_CODES.HONEYCOMB_MR1) interface OnViewDetachedFromWindow { fun onViewDetachedFromWindow(v: View) } @TargetApi(Build.VERSION_CODES.HONEYCOMB_MR1) interface OnViewAttachedToWindow { fun onViewAttachedToWindow(v: View) }
Java
@TargetApi(VERSION_CODES.HONEYCOMB_MR1) public interface OnViewDetachedFromWindow { void onViewDetachedFromWindow(View v); } @TargetApi(VERSION_CODES.HONEYCOMB_MR1) public interface OnViewAttachedToWindow { void onViewAttachedToWindow(View v); }
Bir işleyicinin değiştirilmesi diğerini etkileyebileceğinden, bu iki özellik için veya her ikisi için de çalışan bir bağdaştırıcıya ihtiyacınız vardır. Aşağıdaki örnekte gösterildiği gibi, her özelliğe bir bağlama ifadesi atanması gerekmediğini belirtmek için ek açıklamada requireAll
değerini false
olarak ayarlayabilirsiniz:
Kotlin
@BindingAdapter( "android:onViewDetachedFromWindow", "android:onViewAttachedToWindow", requireAll = false ) fun setListener(view: View, detach: OnViewDetachedFromWindow?, attach: OnViewAttachedToWindow?) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR1) { val newListener: View.OnAttachStateChangeListener? newListener = if (detach == null && attach == null) { null } else { object : View.OnAttachStateChangeListener { override fun onViewAttachedToWindow(v: View) { attach.onViewAttachedToWindow(v) } override fun onViewDetachedFromWindow(v: View) { detach.onViewDetachedFromWindow(v) } } } val oldListener: View.OnAttachStateChangeListener? = ListenerUtil.trackListener(view, newListener, R.id.onAttachStateChangeListener) if (oldListener != null) { view.removeOnAttachStateChangeListener(oldListener) } if (newListener != null) { view.addOnAttachStateChangeListener(newListener) } } }
Java
@BindingAdapter({"android:onViewDetachedFromWindow", "android:onViewAttachedToWindow"}, requireAll=false) public static void setListener(View view, OnViewDetachedFromWindow detach, OnViewAttachedToWindow attach) { if (VERSION.SDK_INT >= VERSION_CODES.HONEYCOMB_MR1) { OnAttachStateChangeListener newListener; if (detach == null && attach == null) { newListener = null; } else { newListener = new OnAttachStateChangeListener() { @Override public void onViewAttachedToWindow(View v) { if (attach != null) { attach.onViewAttachedToWindow(v); } } @Override public void onViewDetachedFromWindow(View v) { if (detach != null) { detach.onViewDetachedFromWindow(v); } } }; } OnAttachStateChangeListener oldListener = ListenerUtil.trackListener(view, newListener, R.id.onAttachStateChangeListener); if (oldListener != null) { view.removeOnAttachStateChangeListener(oldListener); } if (newListener != null) { view.addOnAttachStateChangeListener(newListener); } } }
Yukarıdaki örnek, View
sınıfının OnAttachStateChangeListener
için setter yöntemi yerine addOnAttachStateChangeListener()
ve removeOnAttachStateChangeListener()
yöntemlerini kullanması nedeniyle biraz karmaşıktır.
android.databinding.adapters.ListenerUtil
sınıfı, bu dinleyicilerin kaydını tutar. Böylece bu dinleyiciler, bağlama bağdaştırıcısında kaldırılabilir.
Nesne dönüşümleri
Otomatik nesne dönüştürme
Bir bağlama ifadesinden Object
döndürüldüğünde, kitaplık, özelliğin değerini ayarlamak için kullanılan yöntemi seçer. Object
, seçilen yöntemin bir parametre türüne yayınlanır. Bu davranış, veri depolamak için ObservableMap
sınıfını kullanan uygulamalarda aşağıdaki örnekte gösterildiği gibi kullanışlıdır:
<TextView
android:text='@{userMap["lastName"]}'
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
İfadedeki userMap
nesnesi, bir değer döndürür. Bu değer, android:text
özelliğinin değerini ayarlamak için kullanılan setText(CharSequence)
yönteminde bulunan parametre türüne otomatik olarak yayınlanır. Parametre türü belirsizse ifadedeki döndürme türünü yayınlayın.
Özel dönüşümler
Bazı durumlarda, belirli türler arasında özel dönüşüm gerekir. Örneğin, bir görünümün android:background
özelliği için Drawable
değeri beklenir ancak belirtilen color
değeri tam sayıdır. Aşağıdaki örnekte Drawable
değeri bekleyen bir özellik gösterilmektedir ancak bunun yerine bir tam sayı sağlanır:
<View
android:background="@{isError ? @color/red : @color/white}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
Bir Drawable
beklendiğinde ve bir tam sayı döndürüldüğünde int
değerini ColorDrawable
biçimine dönüştürün.
Dönüştürmeyi gerçekleştirmek için aşağıdaki gibi BindingConversion
notlu statik bir yöntem kullanın:
Kotlin
@BindingConversion fun convertColorToDrawable(color: Int) = ColorDrawable(color)
Java
@BindingConversion public static ColorDrawable convertColorToDrawable(int color) { return new ColorDrawable(color); }
Ancak, bağlama ifadesinde sağlanan değer türleri tutarlı olmalıdır. Aşağıdaki örnekte gösterildiği gibi aynı ifadede farklı türler kullanamazsınız:
// The @drawable and @color represent different value types in the same
// expression, which causes a build error.
<View
android:background="@{isError ? @drawable/error : @color/white}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
Ek kaynaklar
Veri bağlama hakkında daha fazla bilgi edinmek için aşağıdaki kaynaklara bakın.
Sana Özel
Codelab uygulamaları
Blog yayınları
Sizin için önerilenler
- Not: Bağlantı metni JavaScript kapalıyken gösterilir
- Veri Bağlama Kitaplığı
- Düzenler ve bağlama ifadeleri
- Bağlantıyı görüntüleyin