وحید مروجی
وحید مروجی
خواندن ۳ دقیقه·۲ سال پیش

چطور Adapter تمیز با کارایی بهتر داشته باشیم؟

اگر برنامه نویس اندروید هستید حتما تاحالا از adapter ها استفاده کردید و می دونید که adapter ها وظیفه هندل کردن نمایش آیتم های لیست رو برعهده دارن تا بدون مصرف بیش از اندازه رم، لیست های بینهایت رو نمایش بدن.

و حتما هروقت سراغ پیاده سازی یک adapter رفتید با کدهای اضافی که هربار مجبوریم پیاده سازی کنیم و کلاس ViewHolder که بعد از اومدن binding ها به کدهای اضافی تبدیل شدن، مواجه شدیم.

اگر شماهم مثل من با کم کردن یک خط از کداتون احساس رضایت مندی می کنید، این پست رو تا انتها بخونید تا با هم یک adapter با کدهای خیلی کمتر، اما واقعا با کارایی بیشتر پیاده سازی کنیم ?

پیش نیاز ها:

  • آشنایی با View binding
  • آشنایی با کلاس های Generic
  • آشنایی با Code folding
  • آشنایی با متدهای abstract

نکته: در این پست، تمامی تصاویر متعلق به سه کلاس ViewHodler, BaseAdapter, ExampleAdapter می باشند.


شروع:

در پایین تصویر adapter بهینه نشده رو می بینید که قراره به تصویر دوم تبدیل بشه:

اداپتر بهینه نشده
اداپتر بهینه نشده
اداپتر بهینه شده
اداپتر بهینه شده

مواردی که قراره بهبود پیدا کنن:

  • کدهای تکراری مانند context و items که در تمام adapter ها استفاده می شن، از اینجا حذف می شن.
  • پارامترهای متد onBindViewHolder شخصی سازی می شن تا هربار نیاز نباشه با استفاده از position یک مدل بسازیم یا در این حالت، binding رو از holder بگیریم و بصورت مستقیم بهشون دسترسی داشته باشیم.
  • متدها و کلاس هایی مانند getItemCount و ViewHolder هم که خوانایی کد رو کم می کنن نیازی نیست هربار اینجا صدا زده بشن یا پیاده سازی بشن.
  • همچنین متدهایی هم که کار تکراری انجام می دن اما نمی تونیم به جای دیگه ای منتقلشون کنیم، می تونن با روش folding جلوی چشم نباشن تا خوانایی کد افزایش پیدا کنه.

پیاده سازی:

1. Generic ViewHolder

ViewHolder
ViewHolder

در مرحله اول برای اینکه مجبور نباشیم برای هر adapter یک زیرکلاس ViewHolder بسازیم، می تونیم یک کلاس جنریک ViewHolder بسازیم و برای هر adapter از همین کلاس استفاده کنیم.

این کلاس فقط نیاز داره تا جنس ViewBinding رو بصورت generic دریافت کنه.

1. Generic BaseAdapter

BaseAdapter
BaseAdapter

در مرحه بعد نیاز داریم تا یک کلاس BaseAdapter بسازیم و موارد زیر رو بصورت generic براش مشخص کنیم:

  • جنس ViewBinding با شناسه B
  • جنس لیست آیتم ها با شناسه I
  • جنس ViewHolder با شناسه V


3. Override onBindViewHolder

در کلاس BaseAdapter متد onBindViewHolder رو override می کنیم اما ما نمی خوایم که از همین متد در adapter هامون استفاده کنیم، در نتیجه یک متد بصورت abstract به همین نام (می تونه هر نامی داشته باشه) با پارامترهای دلخواه ایجاد می کنیم و در adapter ها همین متد رو override می کنیم.

BaseAdapter
BaseAdapter

پارامترهایی که من برای این متد درنظر گرفتم، این موارده:

  • پارامتر item : مدلی که هر بار نیاز بود تا توسط position از لیست دریافت کنم
  • پارامتر binding : که هربار نیاز بود از holder دریافت کنم
  • پارامتر position : که هربار باید با متد getAbsoluteAdapterPosition دوباره دریافتش می کردم

4. Folding Constractors

خب می رسیم به مواردی که در adapter ها تکراری هستن و نیازی نیست دائما جلوی چشم باشن و خوانایی کد رو کم کنن.

Adapter
Adapter

همینطور که در کلاس BaseAdapter می بینید از خط 21 تا 30، کدهایی هستن که مقداردهی های اولیه رو انجام می دن و مسلما نیازی نیست تا دائما جلوی چشم ما باشن.

در اینجا با استفاده از دو تگ (کامنت) زیر می تونیم این محدوده رو بعنوان code folding معین کنیم تا محیط توسعه این خطوط رو به ما نمایش نده.

//region <name> ... //endregion
Settings
Settings

البته برای این که این محدوده بصورت پیشفرض Collapse باشه و نمایش داده نشه، باید در تنظیمات تیک گزینه Custom folding regions رو فعال کنید.


تمام، adapter ما با حداقل کد و شخصی سازی های مدنظرمون آمادست ?

باقی موارد مثلprotected بودن filed ها در BaseAdapter و Override کردن متد getItemCount در BaseAdapter برای جلوگیری از تکرار و ... فکر نمی کنم نیازی به توضیح داشته باشن و همین موارد گویای کار هست.
اگر سوال یا ابهامی دارید در کامنتا مطرح کنید و اگر شما هم روشی دارید که می شه این آداپتر رو بهینه تر کنیم، خوشحال می شم به تکمیل این پست کمک کنید.

اندرویدrecyclerviewandroiddeveloperبرنامه نویسی
? Android developer, Startup and technology lover
شاید از این پست‌ها خوشتان بیاید