کلاس‌های اتصال تولیدشده

«کتابخانه اتصال داده» کلاس‌های اتصالی تولید می‌کند که می‌توانید از آن‌ها برای دسترسی به متغیرها و نماهای چیدمان استفاده کنید. این سند نحوه ایجاد و سفارشی‌سازی کلاس‌های اتصال تولیدشده را نشان می‌دهد.

کلاس اتصال تولیدشده متغیرهای چیدمان را با نماهای داخل چیدمان پیوند می‌دهد. می‌توانید نام و بسته اتصال را سفارشی‌سازی کنید. همه کلاس‌های اتصال تولیدشده از کلاس ViewDataBinding ارث‌بری می‌کنند.

برای هر فایل چیدمان، یک کلاس اتصال ایجاد می‌شود. به‌طور پیش‌فرض، نام کلاس همان نام فایل چیدمان است که به Pascal case تبدیل شده و پسوند Binding به آن اضافه شده است. بنابراین، برای مثال، اگر نام فایل چیدمان activity_main.xml باشد، کلاس تولیدشده متناظر ActivityMainBinding است. این کلاس همه اتصال‌ها را از ویژگی‌های چیدمان به نماهای چیدمان نگه می‌دارد و می‌داند چگونه مقادیر را برای عبارت‌های اتصال اختصاص دهد.

ایجاد شیء الزام‌آور

شیء اتصال بلافاصله پس‌از گسترش چیدمان ایجاد می‌شود تا اطمینان حاصل شود که سلسله‌مراتب نما قبل‌از اتصال به نماها با عبارت‌های درون چیدمان تغییر نمی‌کند. رایج‌ترین روش برای مقید کردن شیء به چیدمان، استفاده از روش‌های ایستا در کلاس مقیدسازی است. می‌توانید سلسله‌مراتب نما را گسترش دهید و بااستفاده از روش inflate() کلاس اتصال، شیء را به آن متصل کنید، همان‌طور که در مثال زیر نشان داده شده است:

کاتلین

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)

    val binding: MyLayoutBinding = MyLayoutBinding.inflate(layoutInflater)

    setContentView(binding.root)
}

جاوا

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    MyLayoutBinding binding = MyLayoutBinding.inflate(getLayoutInflater());

    setContentView(binding.root);
}

نسخه جایگزینی از روش inflate() وجود دارد که علاوه‌بر شیء LayoutInflater، شیء ViewGroup را نیز می‌گیرد، همان‌طور که در مثال زیر نشان داده شده است:

کاتلین

val binding: MyLayoutBinding = MyLayoutBinding.inflate(getLayoutInflater(), viewGroup, false)

جاوا

MyLayoutBinding binding = MyLayoutBinding.inflate(getLayoutInflater(), viewGroup, false);

اگر چیدمان بااستفاده از سازوکار دیگری گسترده شده است، می‌توانید آن را به‌طور جداگانه به‌صورت زیر متصل کنید:

کاتلین

val binding: MyLayoutBinding = MyLayoutBinding.bind(viewRoot)

جاوا

MyLayoutBinding binding = MyLayoutBinding.bind(viewRoot);

گاهی اوقات نوع اتصال را ازقبل نمی‌دانید. در چنین مواردی، می‌توانید بااستفاده از کلاس DataBindingUtil اتصال را ایجاد کنید، همان‌طور که در تکه‌کد زیر نشان داده شده است:

کاتلین

val viewRoot = LayoutInflater.from(this).inflate(layoutId, parent, attachToParent)
val binding: ViewDataBinding? = DataBindingUtil.bind(viewRoot)

جاوا

View viewRoot = LayoutInflater.from(this).inflate(layoutId, parent, attachToParent);
ViewDataBinding binding = DataBindingUtil.bind(viewRoot);

اگر از موارد اتصال داده در داخل آداپتور Fragment، ListView، یا RecyclerView استفاده می‌کنید، ممکن است ترجیح دهید از روش‌های inflate() کلاس‌های اتصال یا کلاس DataBindingUtil استفاده کنید، همان‌طور که در نمونه کد زیر نشان داده شده است:

کاتلین

val listItemBinding = ListItemBinding.inflate(layoutInflater, viewGroup, false)
// or
val listItemBinding = DataBindingUtil.inflate(layoutInflater, R.layout.list_item, viewGroup, false)

جاوا

ListItemBinding binding = ListItemBinding.inflate(layoutInflater, viewGroup, false);
// or
ListItemBinding binding = DataBindingUtil.inflate(layoutInflater, R.layout.list_item, viewGroup, false);

بازدیدها با شناسه‌ها

«کتابخانه اتصال داده» برای هر نمایی که در چیدمان شناسه دارد، فیلدی تغییرناپذیر در کلاس اتصال ایجاد می‌کند. برای مثال، «کتابخانه اتصال داده» فیلدهای firstName و lastName از نوع TextView را از چیدمان زیر ایجاد می‌کند:

<layout xmlns:android="http://schemas.android.com/apk/res/android">
   <data>
       <variable name="user" type="com.example.User"/>
   </data>
   <LinearLayout
       android:orientation="vertical"
       android:layout_width="match_parent"
       android:layout_height="match_parent">
       <TextView android:layout_width="wrap_content"
           android:layout_height="wrap_content"
           android:text="@{user.firstName}"
   android:id="@+id/firstName"/>
       <TextView android:layout_width="wrap_content"
           android:layout_height="wrap_content"
           android:text="@{user.lastName}"
  android:id="@+id/lastName"/>
   </LinearLayout>
</layout>

کتابخانه نماها، ازجمله شناسه‌ها، را از سلسله‌مراتب نما در یک گذر استخراج می‌کند. این سازوکار می‌تواند سریع‌تر از فراخوانی روش findViewById() برای هر نما در چیدمان باشد.

شناسه‌ها به اندازه زمانی که اتصال داده وجود ندارد ضروری نیستند، اما هنوز مواردی وجود دارد که دسترسی به نماها ازطریق کد ضروری است.

متغیرها

«کتابخانه اتصال داده» برای هر متغیر اعلام‌شده در چیدمان، روش‌های دستیاب تولید می‌کند. برای مثال، چیدمان زیر روش‌های تنظیم‌کننده و دریافت‌کننده را در کلاس مقیدسازی برای متغیرهای user، image، و note تولید می‌کند:

<data>
   <import type="android.graphics.drawable.Drawable"/>
   <variable name="user" type="com.example.User"/>
   <variable name="image" type="Drawable"/>
   <variable name="note" type="String"/>
</data>

ViewStubs

برخلاف نماهای عادی، اشیاء ViewStub به‌عنوان نماهای نامرئی شروع می‌شوند. وقتی نمایان می‌شوند یا به‌طور صریح گسترده می‌شوند، با گسترده کردن چیدمان دیگری، خودشان را در چیدمان جایگزین می‌کنند.

چون ViewStub از سلسله‌مراتب نما ناپدید می‌شود، نمای موجود در شیء اتصال نیز باید ناپدید شود تا بتواند توسط جمع‌آوری زباله ادعا شود. چون نماها نهایی هستند، یک شیء ViewStubProxy جای ViewStub را در کلاس اتصال تولیدشده می‌گیرد، و به شما امکان می‌دهد وقتی ViewStub وجود دارد به آن دسترسی داشته باشید و وقتی ViewStub گسترده می‌شود به سلسله‌مراتب نمای گسترده‌شده دسترسی داشته باشید.

هنگام گسترش چیدمان دیگر، باید برای چیدمان جدید پیوند ایجاد شود. بنابراین، ViewStubProxy باید به ViewStub گوش دهد OnInflateListener و درصورت لزوم، اتصال را برقرار کند. ازآنجایی‌که در هر زمان فقط یک شنونده می‌تواند وجود داشته باشد، ViewStubProxy به شما امکان می‌دهد یک OnInflateListener تنظیم کنید که پس‌از برقراری اتصال آن را فراخوانی می‌کند.

اتصال فوری

وقتی متغیر یا شیء قابل‌مشاهده‌ای تغییر می‌کند، اتصال برای تغییر قبل‌از قاب بعدی زمان‌بندی می‌شود. بااین‌حال، مواقعی وجود دارد که اتصال باید فوراً اجرا شود. برای اجبار به اجرا، از روش executePendingBindings() استفاده کنید.

متغیرهای پویا

گاهی اوقات، کلاس اتصال خاص ناشناخته است. برای مثال، RecyclerView.Adapter که درمقابل چیدمان‌های دلخواه عمل می‌کند، کلاس اتصال خاص را نمی‌شناسد. باید مقدار الزام‌آور را درطول تماس با روش onBindViewHolder() اختصاص دهد.

در مثال زیر، همه چیدمان‌هایی که RecyclerView به آن‌ها متصل می‌شود متغیر item دارند. شیء BindingHolder دارای روش getBinding() است که کلاس پایه ViewDataBinding را برمی‌گرداند.

کاتلین

override fun onBindViewHolder(holder: BindingHolder, position: Int) {
    item: T = items.get(position)
    holder.binding.setVariable(BR.item, item);
    holder.binding.executePendingBindings();
}

جاوا

public void onBindViewHolder(BindingHolder holder, int position) {
    final T item = items.get(position);
    holder.getBinding().setVariable(BR.item, item);
    holder.getBinding().executePendingBindings();
}

رشته پس‌زمینه

می‌توانید مدل داده‌هایتان را در رشته پس‌زمینه تغییر دهید، به‌شرطی که مجموعه نباشد. اتصال داده هر متغیر یا فیلد را درطول ارزیابی بومی‌سازی می‌کند تا از هرگونه مشکل همزمانی جلوگیری شود.

نام کلاس‌های اتصال سفارشی

به‌طور پیش‌فرض، کلاس اتصال براساس نام فایل چیدمان تولید می‌شود، با حرف بزرگ شروع می‌شود، زیرخط‌ها ( _ ) حذف می‌شود، حرف بعدی بزرگ می‌شود، و کلمه Binding به‌عنوان پسوند اضافه می‌شود. برای مثال، فایل چیدمان contact_item.xml کلاس ContactItemBinding را تولید می‌کند. کلاس در بسته databinding زیر بسته واحد قرار می‌گیرد. برای مثال، اگر بسته واحد com.example.my.app باشد، کلاس اتصال در بسته com.example.my.app.databinding قرار می‌گیرد.

کلاس‌های اتصال را می‌توان با تنظیم کردن مشخصه class عنصر data تغییر نام داد یا در بسته‌های مختلف قرار داد. برای مثال، چیدمان زیر کلاس اتصال ContactItem را در بسته databinding در واحد فعلی تولید می‌کند:

<data class="ContactItem">
    ...
</data>

می‌توانید کلاس اتصال را در بسته دیگری با پیشوند کردن نام کلاس با نقطه تولید کنید. مثال زیر کلاس اتصال را در بسته واحد تولید می‌کند:

<data class=".ContactItem">
    ...
</data>

همچنین می‌توانید از نام کامل بسته در جایی که می‌خواهید کلاس اتصال تولید شود استفاده کنید. مثال زیر کلاس اتصال ContactItem را در بسته com.example ایجاد می‌کند:

<data class="com.example.ContactItem">
    ...
</data>

منابع بیشتر

برای کسب اطلاعات بیشتر درباره اتصال داده، منابع اضافی زیر را ببینید.