כיצד להוסיף View Binding לפרויקט אנדרואיד Gradle

View Binding מקל על כתיבת קוד המקיים אינטראקציה עם תצוגות. הנה איך להגדיר אותו בפרויקט אנדרואיד Gradle שלך.

רוב מפתחי האנדרואיד כנראה מכירים את הקלאסי findViewById() שיטה. תעביר לזה מזהה של אחת התצוגות בפריסת ה-XML שלך וזה יחזיר הפניה לגרסה המנופחת של אותה תצוגה. זה הכל בהנחה שהעברת את המזהה הנכון, ושהתצוגה אכן קיימת. findViewById() אין בדיקות מובנות כדי למנוע ממך לנסות לאחזר תצוגה שאינך יכול לאחזר. היכנסו ל-View Binding.

במקום להשתמש findViewById() בכל View שאתה רוצה, View Binding יוצר אוטומטית מחלקה מחייבת עבור כל פריסה XML. כל תצוגה עם מזהה מתווספת אוטומטית לכיתה, כך שתוכל להפנות אליהן ישירות.

הוספת View Binding לפרויקט אנדרואיד Gradle היא פשוטה במיוחד.

הגדרת Gradle

View Binding מופעלת ברמת המודול ב- Gradle. אם יש לך מספר מודולים, תצטרך להפעיל זאת בנפרד עבור כל אחד מהם.

בתוך ה android לחסום ברמת המודול שלך build.gradle, הוסף את האפשרות להפעלת View Binding.

android {
...

buildFeatures {
viewBinding true
}
}

אולי יש אזהרה לגבי גישה לא חוקית, אבל זה באג מוך וניתן להתעלם ממנו בבטחה.

סנכרון הפרויקט ו-View Binding יופעל. זה כזה קל.

שימוש ב-View Binding

יש כמה דרכים להשתמש ב-View Binding, אבל לפני שכל זה יקרה, בואו נדבר על האופן שבו מחלקות הכריכה נוצרות.

תחביר שם מחלקה

נניח שיש לך פריסת XML בשם some_layout.xml. מחלקה המחייבת המקבילה תקרא SomeLayoutBinding. הדפוס הזה תופס עבור כל הקבצים.

כל מילה (מופרדת באמצעות קווים תחתונים בשם הקובץ) תהיה באותיות רישיות, והקוים התחתונים יוסרו. לאחר מכן "מחייב" מתווסף לסוף.

מופע עם תצוגה קיימת

אם כבר ניפחת את קובץ הפריסה ויש לך הפניה לשורש הפריסה, אתה יכול להגיד למחלקה מחייבת View להשתמש בפריסה הקיימת.

קוטלין:

val binding = SomeLayoutBinding.bind(someLayoutRoot /* should be a View instance */)

Java:

SomeLayoutBinding binding = SomeLayoutBinding.bind(someLayoutRoot /* should be a View instance */);

לדוגמה, אם תרצה להשתמש במחלקה מחייבת ב-Fragment, זה ייראה בערך כך.

קוטלין:

classSomeFragment : Fragment(R.layout.some_layout) {
//Lazy initialization means bind() won't be called until "binding" is referenced.
private val binding by lazy { SomeLayoutBinding.bind(view) }

override fun onViewCreated(view: View, savedInstanceState: Bundle?){
super.onViewCreated(view, savedInstanceState)

//Once this method is called, you can start using the binding.
}
}

Java:

publicclassSomeFragmentextendsFragment{
private SomeLayoutBinding binding = null;

publicSomeFragment(){
super(R.layout.some_layout);
}

@Override
publicvoidonViewCreated(View view, Bundle savedInstanceState){
super.onViewCreated(view, savedInstanceState);

//Initialize the binding.
binding = SomeLayoutBinding.bind(view);
}
}

מופע עם New View

כיתת הכריכה יכולה גם לדאוג לניפוח הפריסה עבורכם.

קוטלין:

val binding = SomeLayoutBinding.inflate(layoutInflater /* should be a LayoutInflater instance */)

Java:

SomeLayoutBinding binding = SomeLayoutBinding.inflate(layoutInflater /* should be a LayoutInflater instance */);

שיטה זו שימושית הן בקטעים והן בפעילויות.

א דוגמה לפרגמנט ייראה משהו כמו הבא.

קוטלין:

classSomeFragment : Fragment() {
private val binding by lazy { SomeLayoutBinding.inflate(LayoutInflater.from(requireContext())) }

override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?){
//The "root" of the binding class is the root of its layout.
return binding.root
}
}

Java:

publicclassSomeFragmentextendsFragment{
private SomeLayoutBinding binding = null;

@Override
publicvoidonCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
//Initialize the binding.
binding = SomeLayoutBinding.inflate(inflater);
//The "getRoot()" method of the binding class returns the root of the layout.
return binding.getRoot();
}
}

א פעילות לדוגמה ייראה משהו כמו הבא.

קוטלין:

classSomeActivity : AppCompatActivity() {
private val binding by lazy { SomeLayoutBinding.inflate(layoutInflater) }

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

//This is equivalent to calling "setContentView(R.layout.some_layout)" but allows use of the binding class.
setContentView(binding.root)
}
}

Java:

publicclassSomeActivityextendsAppCompatActivity{
private SomeLayoutBinding binding = null;

@Override
protectedvoidonCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);

//Instantiate the binding.
binding = SomeLayoutBinding.inflate(getLayoutInflater());
//This is equivalent to calling "setContentView(R.layout.some_layout)" but allows use of the binding class.
setContentView(binding.getRoot());
}
}

התייחסות לתצוגות

כעת, כאשר מחלקת ה-View מחייבת מוגדרת ומוכנה לשימוש, הגיע הזמן להשתמש בה בפועל.

נניח את התוכן של some_layout.xml הם משהו כמו הבאים:

 android:
...>
android:
...
/>
android:
...
/>
android:
...>
android:
...
/>
LinearLayout>
LinearLayout>

יש שם הרבה מזהים להתייחסות בקוד. אבל כל עוד יש לך את המעמד המחייב, ההפניה תהיה קלה.

ב-Kotlin, מתייחסים לתצוגות על ידי משתנים התואמים את המזהים שלהם, עם כמה שינויים. מסירים קווים תחתונים והמחרוזת שהתקבלה מכוסה במעטפת גמל. למשל, להתייחסות some_frame_layout מקוד, תשתמש binding.someFrameLayout. ה someFrameLayout המשתנה יהיה מופע של FrameLayout.

val someFrameLayout: FrameLayout = binding.someFrameLayout

ב-Java, מתייחסים לתצוגות באמצעות שיטות גטר התואמות את המזהים שלהן, בפורמט דומה לזה של Kotlin. למשל, להתייחסות some_frame_layout, היית משתמש binding.getSomeFrameLayout(). השיטה תחזיר מופע של FrameLayout.

FrameLayout someFrameLayout = binding.getSomeFrameLayout();

הפניות ל-View משוטחות גם הן בכריכה. מפנה inner_imageview זהה להתייחסות some_frame_layout.

סיכום

כפי שאני בטוח שאתה יכול לראות, View Binding באנדרואיד הוא גם קל ליישום וגם קל לשימוש. במקרים רבים, קל יותר לשימוש מאשר findViewById().

לפרטים נוספים על יישום View Binding, יחד עם כמה דוגמאות, עיין בתיעוד הרשמי של גוגל.