پیاده سازی Adaptive Icon

آفلاین
user-avatar
پوریا شریفی
07 مرداد 1400, خواندن در 6 دقیقه

اندروید O قالب جدیدی از آیکون‌های برنامه را به نام Adaptive Icon معرفی کرد، که برای انسجام بیشتر همه آیکون‌های موجود در دستگاه است. در این پست نحوه ساخت این نوع آیکون برای برنامه شما  را بررسی می‌کنیم. به زودی بسیاری از برنامه‌ها minSdkVersion = 26 هستند، بنابراین این پست همچنین تکنیک‌های افزودن این نوع آیکون را با بیشترین کارایی ممکن بررسی می‌کند.

همچنین لازم به ذکر است که در اندروید استدیو 3.0 به بعد یک wizard جدید برای کمک به شما در ایجاد adaptive icon وجود دارد، که در اینجا به آن‌ها نمی‌پردازیم و به تکنیک‌های اساسی پایبند خواهیم بود.

اصول

Adaptive icon نوع جدید drawable است، یعنی AdaptiveIconDrawable اما شما هرگز نیازی به کار مستقیم با کلاس نخواهید داشت، بلکه باید آن را در xml تعریف کنید و manifest به آن ارجاع دهید. می‌توانید با فرمت زیر این کار را انجام دهید:

<adaptive-icon>
  <background android:drawable="@[drawable|mipmap|color]/bar"/>
  <foreground android:drawable="@[drawable|mipmap|color]/foo"/></adaptive-icon>

هر طرح باید اندازه 108dp*108dp داشته باشد. Drawableهای پس‌زمینه باید مات باشند در حالی که پیش‌زمینه‌ها می‌توانند حاوی شفافیت باشند.

شما همچنین باید apk خود را با buildToolsVersion 26.0.0 یا بالاتر بسازید.

در واقع minSDK 26 است

از آنجا که adaptive icon فقط در api 26+ استفاده می‌شود، می‌توانید به ویژگی‌هایی که در دسترس شماست تکیه کنید. که پشتیبانی بسیار خوبی از VectorDrwable دارد.

استفاده از vectorها بسیار جذاب است زیرا به ما این امکان را می‌دهد که یک بار drawable را در یک قال جمع و جور مشخص کنیم. این یعنی بدون افزایش حجم apk در هر رزولوشنی نمایش داده می‌شود.

به نظر نمی‌رسد که اکثر توسعه دهندکان از مزایای VectorDrawable gradient استفاده کنند. توصیه می‌کنم که این پست lan lake را که اصول adaptive icon را پوشش می‌دهد مطالعه کنید.

Lan نحوه استفاده از gradient خطی را نشان می‌دهد، اما VectorDrawable چند ترفند دیگر نیز دارد. در اینجا مثالی از  اجرای سایه بلند با استفاده از یک شیب شعاعی با چندین توقف رنگ وجود دارد. من همچنین از inline resource syntax استفاده می‌کنم که به شما امکان می‌دهد چندین پرونده را در یک فایل واحد جاسازی کنید (از طریق ترفندهای AAPT که معمولاً در AnimatedVectorDrawable استفاده می‌شود).

<vector ...>
  <path android:name="long-shadow"
        android:pathData="...">
    <aapt:attr name="android:fillColor">
      <gradient
          android:type="radial"
          android:centerX="54"
          android:centerY="54"
          android:gradientRadius="76.37">
        <!-- 15% black from center to 32% stop -->
        <item android:offset="0.0" android:color="#26000000" />
        <item android:offset="0.32" android:color="#26000000" />
        <!-- 2% black at 62% stop -->
        <item android:offset="0.62" android:color="#05000000" />
        <!-- fade to transparent -->
        <item android:offset="1.0" android:color="#00000000" />
      </gradient>
    </aapt:attr>
  </path>
  ...
</vector>

اکثر آیکون‌ها نوعی از عنصر drop-shadow را در خود دارند (طبق راهنمای متریال دیزاین) که متاسفانه VectorDrawble از آن پشتیبانی نمی‌کند، در adaptive icon دو ویژگی وجود دارد که vectorها را بیشتر مرتبط می‌کند:

  1. Launcher وظیفه پوشاندن drawable کلی و ایجاد drop shadow برای کل شکل را دارد، دیگر لازم نیست برای کل شکل سایه ایجاد کنید.
  2. آیکون از یک پس‌زمینه و یک تصویر پیش‌زمینه تشکیل شده است، بنابراین اگر یکی از آن‌ لایه‌ها به هیچ سایه‌ای نیاز نداشته باشد، می‌تواند از مزیت vector بهره ببرد.

برخی از از سایه‌های ساده را می‌توان با استفاده از gradient ساخت اما همه سایه‌ها را نمی‌توان با آن ایجاد کرد.

حداقل Raster مناسب

اگر نمی‌توانید طرح خود را با vectorها پیاده کنید، انجام این کار با استفاده از png کاملا خوب است. آیکون lancher برنامه شما قطعاً بسیار مهم است که ارزش چند بایت اضافی را دارد.

با این وجود یک ترفند خوب وجود دارد که می‌توانید در assetها دارای شفافیت از آن استفاده کنید. که معمولاً در پیش‌زمینه‌های adaptive icon از آن استفاده می‌شود. در حالی که این نوع asset در زمان ساخت به خوبی فشرده می‌شود، اما در زمان اجرا هر پیکسل 8 بیت حافظه اشغال می‌کند و مهم نیست که شفافیت آن چقدر است. برای به حداقل رساندن این مورد، اگر شفافیت‌ در لبه‌ها است می‌توانید این مناطق را از png پاک کنید و از یک InsetDrawable برای بسته‌بندی و تغییر اندازه آن به 108 dp استفاده کنید. متاسفانه InsetDrawable دوست ندارد اندازه آن تغییر کند (برای مثال اگر top inset را 16 dp تنظیم کنید همیشه 16dp خواهد بود و مهم نیست که اندازه drawble تغییر کند) بنابراین در api 26، functional inset اضافه شد، که به شما اماکن می‌دهد insetها را به عنوان درصدی از drawable کلی مشخص کنید، بنابراین مقیاس آن‌ها درست می‌شود.

به عنوان مثال فرض کنید شما یک asset پیش‌زمینه دارید که 54dp * 54dp است، به جای قرار دادن آن در میان asset شفاف 108dp * 108dp می‌توان از کد زیر استفاده کرد.

<inset ...
    android:drawable="@mipmap/ic_fg_trimmed"
    android:insetLeft="25%"
    android:insetTop="25%"
    android:insetRight="25%"
    android:insetBottom="25%" />

در اینجا مثالی از این تکنیک آورده شده است که در آن قسمت بالا/چپ asset را که شفاف است را حذف می‌کنیم و نسخه اصلاح شده را قرار می‌دهیم، در غیر اینصورت آیکون دارای شفافیت است.

توجه داشته باشید که هنوز مجبورید assetهای raster را در تراکم‌های مختلف تهیه کنید، اما حداقل هر کدام کوچکتر و اندازه حافظه بسیار کاهش می‌یابد.

میانبر

Adaptive iconها فقط برای آیکون‌های برنامه نیستند، بلکه برای میانبرهای برنامه نیز استفاده می‌شوند. میانبرهای برنامه را می‌توان به صفحه اصلی وصل کرد بنابراین باید با نمادهای برنامه متناسب باشد. Design specs (قبل از اندروید o) آیکون‌های میانبر را برای قرارگرفتن روی یک پس‌زمینه خاکستری فراخوانی می‌کند. در اندروید o، پس‌زمینه باید ماسک adaptive icon را پر کند. اگر به حالت adaptive بروز نکنید، آیکون میانبر شما کوچک شده و روی پس‌زمینه قرار می‌گیرد.

برای پیاده سازی برنامه Plaid، من ابتدا آیکون‌های جدیدی را در پیکربندی v26 اضافه کردم که برای adaptive grid و keyline دوباره طراحی شده است. من از این روش راضی نبودم زیرا آن‌ها اساساً نسخه‌های کوچک آیکون‌های v25 بودند. یعنی من الان دو آیکون برای نگه داری داشتم. در نهایت تصمیم گرفتم که آیکون v25 را به یک پیش‌زمینه(به عنوان مثال آیکون جستجو) و پس‌زمینه(دایره خاکستری) تبدیل کنم و آن‌ها را با یک LayerDrawable ترکیب کنم.

<layer-list ...>
  <item android:drawable="@drawable/ic_app_shortcut_background"/>
  <item android:drawable="@drawable/ic_shortcut_search_foreground"/>
</layer-list>

سپس می‌توانم از همان asset پیش‌زمینه در adaptive icon استفاده کنم. در v25 آیکون‌های میانبر 24dp در داخل asset، 48dp هستند، در v26، 44dp در داخل asset، 108dp هستند:

برای استفاده از همان فایل 48dp لازم بود که آن را inset کنم، به طوری که آیکون پس از کوچک شدن اندازه مناسبی (vectorها) در adaptive icon اندازه 108dp داشته باشد.

<adaptive-icon ...>
  <background android:drawable="@color/light_grey" />
  <foreground>
    <!-- 10dp padding on each side of 108dp asset -->
    <inset
      android:drawable="@drawable/ic_shortcut_search_foreground"
      android:inset="9.26%" />
  </foreground>
</adaptive-icon>

AdaptiveIconDrawable، asset عرضه شده را به 108dp تقسیم می‌کند، بنابراین برای محاسبه محتوای مورد نیاز برای تولید یک آیکون باید: 48/24 * 44 = 88، یعنی ما باید هر طرف asset بزرگ شده را 10dp، inset کنیم: 10 / 108 -> 9.26%

برای میانبرهایی که Bitmap هستند، از Icon#createWithAdaptiveBitmap استفاده کنید.

Play around

اگر در حال ساختن یک adaptive icon هستید، احتمالاً برنامه Adaptive Icon Playground برای شما مفید است. این برنامه  به شما امکان می‌دهد adaptive icon را بروی دستگاه خود مشاهده کنید، ببینید که آن‌ها چگونه با ماسک‌های مختلف اعمال می‌شوند.

می‌توانید APK آن را برای دستگاه‌هایی که اکنون دارای اندروید o هستند دریافت کنید و یا آن را در گیت‌هاب بررسی کنید.

منبع

چه امتیازی به این مقاله می دید؟
خیلی بد
بد
متوسط
خوب
عالی

دیدگاه‌ها و پرسش‌ها

برای ارسال دیدگاه لازم است، ابتدا وارد سایت شوید.

در حال دریافت نظرات از سرور، لطفا منتظر بمانید

در حال دریافت نظرات از سرور، لطفا منتظر بمانید

آفلاین
user-avatar
پوریا شریفی @pouryasharifi78
ابتدا که با برنامه‌نویسی آشنا شدم به سمت php و طراحی وب رفتم، بعد از اون به توسعه‌ی اندروید علاقه‌مند شدم و تقریبا ۲ سال است که مشغول به برنامه‌نویسی...
دنبال کردن

گفتگو‌ برنامه نویسان

بخشی برای حل مشکلات برنامه‌نویسی و مباحث پیرامون آن وارد شو