حسام رسولیان

بررسی قابلیت view binding در اندروید استودیو

  • نوشته شده در 01 فروردین 1399
  • توسط
  • در آموزش

در نسخه جدید محیط برنامه نویسی اندروید استودیو ۳٫۶ ویژگی جدیدی به نام view binding معرفی شده است که میتوانید جایگزین دستورهای تکراری findViewById کنید و از نوشتن کدهای تکراری و تولید باگ اجتناب کنید.

برای فعال کردن view binding نیاز به کتابخانه خاصی نیست و این کار از طریق گریدل انجام میشه.

این کار توسط ساخته شدن یک binding آبجکت که شامل ویژگی های view به همراه آیدی می باشد انجام می شود.

این قابلیت از هر دو زبان جاوا و کاتلین پشتیبانی میکنید.

فعال کردن view binding

برای استفاده از view binding نیازی به وارد کردن کتابخانه خارجی به پروژه نداریم.

این کار از طریق فعالسازی در پلاگین گریدل داخل خود اندروید استودیو انجام می شود.

برای فعال کردن وارد فایل build.gradle نسخه ماژول شوید و از دستور زیر استفاده کنید.

android {
    viewBinding {
        enabled = true
    }
}

در نسخه اندروید استودیو ۴٫۰ به شکل زیر باید عمل کنید.

android {
    buildFeatures {
        viewBinding = true
    }
}

با فعالسازی view binding به طور خودکار برای تمام فایل های لایه شما کلاس های متناسب با همان ساخته می شود.

استفاده view binding در اکتیویتی

فرض میکنیم یک لایه به نام activity_awesome.xml داریم که شامل یک دکمه و دو عدد TextView هست.

در این حالت کلاسی به نام ActivityAwesomeBinding ساخته می شود که شامل یک ویژگی برای هر view می باشد.

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    val binding = ActivityAwesomeBinding.inflate(layoutInflater)

    binding.title.text = "Hello"
    binding.subtext.text = "Concise, safe code"
    binding.button.setOnClickListener { /* ... */ }

    setContentView(binding.root)
}

تگ ریشه در فایل xml همیشه به نام root  ذخیره می شود.

در اکتیویتی از این root در setContentView استفاده میکنیم.

اگر در setContentView(…) از آیدی لایه استفاده کنید مرتکب اشتباه ساده ای شده اید.

به دلیل اینکه این کار باعث می شود لایه مورد نظر دوبار فراخوانی و مقدار دهی شود.

راه حل استفاده از آبجکت binding می باشد, setContentView(binding.root).

کدهای ایمن با آبجکت binding 

دستور findViewById یکی از علت های به وجود آمدن باگ در برنامه نویسی اندروید هست.

خیلی راحت میتونید به اشتباه آیدی یک کامپوننت دیگر را قرار دهید و اپلکییشن با این کار کرش میکند.

Type-safe: در این حالت همیشه تایپ درستی از اطلاعات مقدار دهی می شود. به دلیل اینکه هر نوع کامپوننتی که شما در لایه قرار میدهید یک فیلد از همان نوع در کلاس ساخته می شود و هیچوقت اشتباهی رخ نمیدهد.

زمانی که فایل xml لایه را ویرایش میکنید, فقط تغییرات اعمال شده در کلاس تولید شده بروزرسانی می شود.

این به این معنی هست که تغییرات بلافاصله اعمال میشود و نیازی به بیلد کردن پر.ژه نیست.

بیاید نگاهی به کد های تولید شده برای لایه خودمون بندازیم.

public final class ActivityAwesomeBinding implements ViewBinding {
  @NonNull
  private final ConstraintLayout rootView;
  @NonNull
  public final Button button;
  @NonNull
  public final TextView subtext;
  @NonNull
  public final TextView title;

همونطور که مبینید لایه اصلی فایل ما به نام rootView  هست و برای بقیه کامپوننت یک فیلد با همان آیدی تعریف شده است.

این کلاس هیچ بخش منطقی ندارد و فقط کار نگهداری view ها را انجام می دهد.

  private ActivityAwesomeBinding(@NonNull ConstraintLayout rootView, @NonNull Button button,
      @NonNull TextView subtext, @NonNull TextView title) { … }
  
  @NonNull
  public static ActivityAwesomeBinding inflate(@NonNull LayoutInflater inflater) {
    /* Edited: removed call to overload inflate(inflater, parent, attachToParent) */
    View root = inflater.inflate(R.layout.activity_awesome, null, false);
    return bind(root);
  }

قسمت هیجان انگیز این بخش استفاده از متد bind هست که یک inflated layout دریافت میکند و تمام فیلدهای کلاس و view ها را بررسی و مقداردهی میکند, همچنین وظیفه بررسی خطا را هم انجام میدهد.

  @NonNull
  public static ActivityAwesomeBinding bind(@NonNull View rootView) {
    /* Edit: Simplified code – the real generated code is an optimized version */
    Button button = rootView.findViewById(R.id.button);
    TextView subtext = rootView.findViewById(R.id.subtext);
    TextView title = rootView.findViewById(R.id.title);
    if (button != null && subtext != null && title != null) {
      return new ActivityAwesomeBinding((ConstraintLayout) rootView, button, subtext, title);
    }
    throw new NullPointerException("Missing required view […]");
  }

در کدهای کلاس ایجاد شده سه متد داریم که کار ساخت آبجکت و برای ما انجام میدهند.

inflate(inflater): از این متد در قسمت onCreate اکتیویتی ها استفاده میکنیم که هیچ view والدی نداریم.

inflate(inflater, parent, attachToParent): از این متد در فرگمنت یا اداپتر ها استفاده میکنیم یعنی جایی که نیاز داریم یک ViewGroup به آن پاس دهیم.

bind(rootView): از این متد هم جایی استفاده میکنیم که قبلا لایه خودمون رو به کدها متصل کردیم و حالا فقط میخوایم که از نوشتن findViewById پرهیز کنیم.

نظر دهید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

دو + سیزده =