View binding جزء من Android Jetpack.
ربط العناصر هي ميزة تسهّل كتابة رمز برمجي يتفاعل مع العناصر. بعد تفعيل ربط العرض في إحدى الوحدات، يتم إنشاء class binding لكل ملف تنسيق XML متوفّر في تلك الوحدة. يحتوي مثيل لفئة الربط على مراجع مباشرة إلى جميع طرق العرض التي لها معرّف في التنسيق المناظر.
في معظم الحالات، يحلّ ربط العرض محلّ findViewById
.
ضبط إعدادات الجهاز
يتم تفعيل ربط العرض على أساس كل وحدة على حدة. لتفعيل ربط العناصر في
وحدة، اضبط خيار الإنشاء viewBinding
على true
في ملف
build.gradle
على مستوى الوحدة، كما هو موضّح في المثال التالي:
رائع
android { ... buildFeatures { viewBinding true } }
Kotlin
android { ... buildFeatures { viewBinding = true } }
إذا أردت تجاهل ملف تنسيق أثناء إنشاء فئات الربط، أضِف سمة tools:viewBindingIgnore="true"
إلى العرض الجذر لملف التنسيق:
<LinearLayout
...
tools:viewBindingIgnore="true" >
...
</LinearLayout>
الاستخدام
في حال تفعيل ربط العرض لوحدة، يتم إنشاء فئة ربط لكل ملف تنسيق XML يحتوي عليه النموذج. تحتوي كل فئة ربط على إحالات إلى العرض الجذر وجميع العروض التي لها رقم تعريف. يتم إنشاء اسم فئة الربط من خلال تحويل اسم ملف XML إلى تنسيق Pascal case وإضافة الكلمة "Binding" في النهاية.
على سبيل المثال، ملف تنسيق يُسمى result_profile.xml
يحتوي على
ما يلي:
<LinearLayout ... >
<TextView android:id="@+id/name" />
<ImageView android:cropToPadding="true" />
<Button android:id="@+id/button"
android:background="@drawable/rounded_button" />
</LinearLayout>
تُسمى فئة الربط التي تم إنشاؤها ResultProfileBinding
. تحتوي هذه الفئة على
حقلين: TextView
باسم name
وButton
باسم button
. لا يحتوي العنصر
ImageView
في التنسيق على معرّف، لذا لا تتم الإشارة إليه في
فئة الربط.
تتضمّن كل فئة ربط أيضًا طريقة getRoot()
، ما يقدّم مرجعًا مباشرًا
للعرض الجذر لملف التنسيق المقابل. في هذا المثال، تعرض المحاولة
getRoot()
في فئةResultProfileBinding
المحاولة
LinearLayout
العرض الجذر.
توضِّح الأقسام التالية استخدام فئات الربط التي تم إنشاؤها في الأنشطة والشرائح.
استخدام ربط العرض في الأنشطة
لإعداد مثيل لفئة الربط لاستخدامه مع نشاط، نفِّذ الخطوات التالية في onCreate()
النشاط:
- استدعاء طريقة
inflate()
الثابتة المضمّنة في فئة الربط التي تم إنشاؤها يؤدي ذلك إلى إنشاء مثيل لفئة الربط لاستخدامه في النشاط. - يمكنك الحصول على مرجع إلى طريقة العرض الجذر من خلال استدعاء طريقة
getRoot()
أو باستخدام بنية Kotlin. - نقْل العرض الجذر إلى
setContentView()
لجعله العرض النشط على الشاشة.
يتم عرض هذه الخطوات في المثال التالي:
Kotlin
private lateinit var binding: ResultProfileBinding override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) binding = ResultProfileBinding.inflate(layoutInflater) val view = binding.root setContentView(view) }
Java
private ResultProfileBinding binding; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); binding = ResultProfileBinding.inflate(getLayoutInflater()); View view = binding.getRoot(); setContentView(view); }
يمكنك الآن استخدام مثيل فئة الربط للإشارة إلى أيّ من طرق العرض:
Kotlin
binding.name.text = viewModel.name binding.button.setOnClickListener { viewModel.userClicked() }
Java
binding.name.setText(viewModel.getName()); binding.button.setOnClickListener(new View.OnClickListener() { viewModel.userClicked() });
استخدام ربط العرض في الأجزاء
لإعداد مثيل لفئة الربط لاستخدامه مع جزء، نفِّذ الخطوات التالية في onCreateView()
طريقة الجزء:
- استدعاء الطريقة الثابتة
inflate()
المضمّنة في فئة الربط التي تم إنشاؤها يؤدي ذلك إلى إنشاء مثيل لفئة الربط لاستخدامه في المقتطف. - يمكنك الحصول على مرجع إلى طريقة العرض الجذر من خلال استدعاء طريقة
getRoot()
أو باستخدام بنية Kotlin. - ارجع العرض الجذر من الطريقة
onCreateView()
لجعله العرض النشط على الشاشة.
Kotlin
private var _binding: ResultProfileBinding? = null // This property is only valid between onCreateView and // onDestroyView. private val binding get() = _binding!! override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { _binding = ResultProfileBinding.inflate(inflater, container, false) val view = binding.root return view } override fun onDestroyView() { super.onDestroyView() _binding = null }
Java
private ResultProfileBinding binding; @Override public View onCreateView (LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { binding = ResultProfileBinding.inflate(inflater, container, false); View view = binding.getRoot(); return view; } @Override public void onDestroyView() { super.onDestroyView(); binding = null; }
يمكنك الآن استخدام مثيل فئة الربط للإشارة إلى أيّ من طرق العرض:
Kotlin
binding.name.text = viewModel.name binding.button.setOnClickListener { viewModel.userClicked() }
Java
binding.name.setText(viewModel.getName()); binding.button.setOnClickListener(new View.OnClickListener() { viewModel.userClicked() });
تقديم نصائح حول الإعدادات المختلفة
عند تحديد طرق العرض في عمليات ضبط متعدّدة، قد يكون من المفيد في بعض الأحيان استخدام نوع عرض مختلف استنادًا إلى التنسيق المحدّد. يوضّح مقتطف الرمز التالي مثالاً على ذلك:
# in res/layout/example.xml
<TextView android:id="@+id/user_bio" />
# in res/layout-land/example.xml
<EditText android:id="@+id/user_bio" />
في هذه الحالة، قد تتوقّع أن تعرض الفئة التي تم إنشاؤها حقل userBio
من النوع TextView
، لأنّ TextView
هي الفئة الأساسية الشائعة. بسبب
قيود فنية، لا يمكن لأداة إنشاء رموز ربط العروض تحديد ذلك، ولذلك
تنشئ حقل View
بدلاً من ذلك. يتطلّب ذلك تحويل الحقل لاحقًا باستخدام
binding.userBio as TextView
.
للتغلب على هذا القيد، يتيح ربط العرض استخدام سمة tools:viewBindingType
، ما يتيح لك إخبار المُجمِّع بالنوع الذي يجب استخدامه في الرمز الذي تم إنشاؤه.
في المثال السابق، يمكنك استخدام هذه السمة لجعل المُجمِّع
ينشئ الحقل على أنّه TextView
:
# in res/layout/example.xml (unchanged)
<TextView android:id="@+id/user_bio" />
# in res/layout-land/example.xml
<EditText android:id="@+id/user_bio" tools:viewBindingType="TextView" />
في مثال آخر، لنفترض أنّ لديك تنسيقَين، أحدهما يحتوي على
BottomNavigationView
والآخر يحتوي على NavigationRailView
. تمتد كلتا کلاستَي NavigationBarView
، اللتين تحتويان على معظم تفاصيل التنفيذ. إذا لم يكن رمزك البرمجي بحاجة إلى معرفة الفئة الفرعية المحدّدة المتوفّرة في
التنسيق الحالي، يمكنك استخدام tools:viewBindingType
لضبط نوع
العنصر الذي تم إنشاؤه على NavigationBarView
في كلا التنسيقَين:
# in res/layout/navigation_example.xml
<BottomNavigationView android:id="@+id/navigation" tools:viewBindingType="NavigationBarView" />
# in res/layout-w720/navigation_example.xml
<NavigationRailView android:id="@+id/navigation" tools:viewBindingType="NavigationBarView" />
لا يمكن لربط العرض التحقّق من قيمة هذه السمة عند إنشاء الرمز. لتجنُّب أخطاء وقت الترجمة ووقت التشغيل، يجب أن تستوفي القيمة الشروط التالية:
- يجب أن تكون القيمة فئة ترث من
android.view.View
. يجب أن تكون القيمة فئة فائقة للعلامة التي يتم وضعها عليها. على سبيل المثال، لا تعمل القيم التالية:
<TextView tools:viewBindingType="ImageView" /> <!-- ImageView is not related to TextView. --> <TextView tools:viewBindingType="Button" /> <!-- Button is not a superclass of TextView. -->
يجب أن يتم حلّ النوع النهائي بشكلٍ متسق في جميع الإعدادات.
الاختلافات عن findViewById
يقدّم ربط العرض مزايا مهمة مقارنةً باستخدام findViewById
:
- أمان القيم الخالية: بما أنّ ربط العناصر ينشئ إحالات مباشرة إلى العناصر،
لا يُحتمل حدوث استثناء مؤشر فارغ بسبب معرّف عنصر غير صالح.
بالإضافة إلى ذلك، عندما لا يظهر عرض إلا في بعض إعدادات ملف تخطيط، يتم وضع علامة
@Nullable
على الحقل الذي يحتوي على مرجعه في فئة الربط. - أمان النوع: تحتوي الحقول في كل فئة ربط على أنواع تتطابق مع العروض التي تشير إليها في ملف XML. وهذا يعني أنّه ما مِن خطر بحدوث استثناء عند محاولة تحويل مثيل فئة.
تعني هذه الاختلافات أنّ حالات عدم التوافق بين التنسيق والرمز المبرمَج تؤدي إلى تعذُّر إنشاء التطبيق في وقت الترجمة بدلاً من وقت التشغيل.
المقارنة مع ربط البيانات
يُنشئ كلّ من ربط العناصر المرئية وربط البيانات فئات ربط يمكنك استخدامها للإشارة إلى العناصر المرئية مباشرةً. ومع ذلك، يهدف ربط الاطِّلاع إلى التعامل مع حالات استخدام أبسط ويقدّم الفوائد التالية مقارنةً بربط البيانات:
- الترجمة أسرع: لا يتطلّب ربط العناصر معالجة التعليقات التوضيحية، لذا تكون أوقات الترجمة أسرع.
- سهولة الاستخدام: لا يتطلّب ربط العناصر بالعرض استخدام ملفات تنسيق XML مُشارَك إليها بشكل خاص، لذا يمكن اعتماده في تطبيقاتك بشكل أسرع. بعد تفعيل ربط العرض في وحدة، يتم تطبيقه على جميع تنسيقات هذه الوحدة تلقائيًا.
من ناحية أخرى، فإنّ ربط العرض له القيود التالية مقارنةً بربط data:
- لا يتيح ربط العرض استخدام متغيّرات التنسيق أو تعبيرات التنسيق، لذا لا يمكن استخدامه لتعريف محتوى واجهة المستخدم الديناميكية مباشرةً من ملفات تنسيق XML.
- لا يتيح ربط العرض ربط البيانات في الاتجاهين.
وبناءً على هذه الاعتبارات، من الأفضل في بعض الحالات استخدام كلّ من ربط الاطِّلاع وربط البيانات في المشروع. يمكنك استخدام ربط البيانات في التنسيقات التي تتطلب ميزات متقدّمة واستخدام ربط العرض في التنسيقات التي لا تتطلّب ذلك.
مصادر إضافية
لمزيد من المعلومات عن ربط العناصر، اطّلِع على المراجع الإضافية التالية:
المدوّنات
الفيديوهات
أفلام مُقترَحة لك
- ملاحظة: يتم عرض نص الرابط عندما تكون لغة JavaScript غير مفعّلة.
- الانتقال من العناصر التركيبية في Kotlin إلى ربط عرض Jetpack
- التنسيقات وتعبيرات الربط
- هندسة التطبيق: طبقة واجهة المستخدم - بدء الاستخدام - مطوّرو تطبيقات Android