ایجاد تم تیره در اندروید ۱۰


چگونه در اندروید برنامه ای با تم تیره بسازیم؟

بلاخره در اندروید 10 از دارک تم یا تم تیره برای UI رونمایی شد. امکان جذابی که همیشه جای خالی آن در UI دیده می شد. البته پشتیبانی از تم تیره امکانی بود که در نسخه های دیگر هم پشتیبانی می شد. اما در اندروید 10 گزینه system-level به تنظیمات اصلی دیوایس اندرویدی افزوده شد. با وجود این قابلیت می توان می توان تم تیره را بجز برنامه های مشخص، روی تمام UI دیوایس پیاده نمود.

در این مقاله به پیاده سازی دارک تم روی یک برنامه اندرویدی به زبان کاتلین و در اندروید استودیو 3.5 می پردازیم. توجه داشته باشید که در این مثال تم اصلی برنامه تغییر می کند نه متن pdf.

مزایای استفاده از تم تیره

  • افزایش عمر باتری : در بسیاری از دیوایس ها با صفحه نمایش OLED با استفاده از dark theme پیکسل های صفحه کار کمتری انجام می دهند و در نتیجه عمر باتری بیشتر می شود.
  • وضوح : در محیط هایی با نور کم تجربه کاربری بهتری ایجاد می کند.
  • دسترسی بهتر : برای کاربرانی که به نور زیاد حساسیت دارند.

 

آشنایی با طرح پروژه

در این پروژه می خواهیم یک برنامه pdf خوان بسازیم. برای چنین برنامه هایی قابلیت تنظیم تم در حالت روشن یا تاریک امکان متداولی ست. در این قسمت از آموزش به شرح چگونه فعال شدن این قابلیت می پردازیم.

برنامه ای که برای خواندن فایل هایی با فرمت pdf ساخته ایم به شکل زیر می باشد. توجه داشته باشید که این تست روی emulator ی با اندروید 10 اجرا شده است.

با انتخاب dark theme از بخش quick setting همانند شکل زیر :

با انتخاب این گزینه مشاهده می کنید که UI دیوایس تغییر کرده اما برنامه مورد نظر تغییری نکرده است.

Force Dark یا تحمیل حالت تیره

سریع ترین راه برای عملی نمودن تم تیره در برنامه پیاده سازی Force Dark می باشد. قابلیتی که در اندروید 10 به راحتی دارک تم را برای برنامه فعال می سازد. حتی اگر برنامه شما برای امکان dark theme برنامه نویسی نشده باشد، تنها با تغییر گزینه force-dark در قسمت تنظیمات developer option می توان به سرعت این قابلیت را ایجاد نمود.

Force Dark در زمان render شدن برنامه اجرا می شود. view های ساخته شده را دنبال می کند. سپس تصمیم می گیرد کدام view امکان نمایش dark theme را دارد.

قبل از پیاده سازی Force Dark مطمئن شوید که برنامه را برای اندروید 10 تنظیم کرده اید. یعنی minsdkversion و targetsdkversion روی 29 ست شده باشد.

پیاده سازی Force Dark

ایجاد تم در فایل style.xml :

<style name="AppTheme" parent="Theme.MaterialComponents.Light">
  ...

  <item name="android:forceDarkAllowed">true</item>
</style>

با true قرار دادن مقدار android:forceDarkAllowed به سادگی این امکان فعال شده و نتیجه به صورت زیر خواهد بود :

برای غیر فعال نمودن تم تیره در این روش کافی ست در فایل xml از تغییر مقدار attribute مربوطه روی false (یعنی android:forceDarkAllowed) و از بخش کد برنامه با استفاده از متد ()setForceDarkAllowed عملی می گردد.

این روش با افزودن یک خط عملی می شود اما دو مشکل وجود دارد : اول اینکه برنامه کاملا hard code شده عمل می کند و دیگر کنترلی بر این عملکرد نخواهید داشت. دوم اینکه بدیهی ست تنها برای اندروید 10 کاربردی ست.

از طرفی این روش به خاطر نداشتن کنترل روی آن روش مناسبی نیست. فرض کنید در view برنامه یک imageView وجود داشته باشد که مشمول این force dark شود و تصویر به خوبی نمایش داده نمی شود.

راه حل دیگر پیاده سازی یک custom theme می باشد.

تم DayNight

DayNight تمی از کتابخانه AppCompat است که امکان ساخت تم سفارشی تیره را برای برنامه فراهم می آورد. استفاده از این قابلیت از اندروید 14 به بالا امکان پذیر است.

در فایل styles.xml، ابتدا خط مربوط به force dark را کامنت می کنیم. سپس Apptheme را به صورت زیر کلاس DayNight قرار می دهیم.

<style name="AppTheme" parent="Theme.MaterialComponents.DayNight">

در واقع DayNight بخشی از jetpack در اندروید است که به کمک آن می توان به پیاده سازی های material design های متنوع پرداخت.

بهترین روش برای استفاده از MaterialComponents استفاده از AppCompat می باشد که از بازنویسی بسیاری از عناصر UI پیشگیری می کند.

افزودن رنگ های مناسب به فایل colors.xml

با کمک مسیر values-night ► New ► Android resource و ایجاد colors.xml :

<resources>

  <color name="ic_settings_color">#FFFFFFFF</color>
  <color name="ic_attachment_color">#FFFFFFFF</color>
  <color name="background_color">#FF808080</color>
  <color name="ic_color_lens_color">#FFFFFFFF</color>

</resources>

با فعال نمودن تم تیره در برنامه خروجی به صورت زیر می شود :

به طور پیش فرض وقتی از DayNight ارث بری می شود، تنظیمات اصلی دیوایس دنبال می گردد. و در واقع تم تاریک بر روی همه اکتیویتی ها اعمال می شود.

override نمودن تنظیمات سیستم برای dark mood یا حالت تیره

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

کاربر می تواند یکی از این گزینه ها را انتخاب نماید :

  • MODE_NIGHT_FOLLOW_SYSTEM : این گزینه ای ست که پیش از انتخاب کاربر انتخاب شده و از تنظیم تم اصلی دیوایس پیروی می کند. این حالت فقط روی اندروید 10 جواب می دهد. چون در تنظیمات دیوایس چنین گزینه ای برای انتخاب وجود دارد.
  • MODE_NIGHT_NO : بدون در نظر گرفتن تنظیمات سیستم همیشه از تم روشن پیروی می کند.
  • MODE_NIGHT_YES : بدون در نظر گرفتن تنظیمات سیستم همیشه از تم تاریک پیروی می کند.
  • MODE_NIGHT_AUTO_BATTERY :  وقتی در تنظیمات دیوایس battery saver فعال باشد از تم تیره استفاده می شود. هم چنین در حالتی که battery saver روشن است و دیوایس در حال شارژ باشد برنامه با تم روشن اجرا می شود.

ساخت این گزینه ها به کمک فیلدهای ثابت کلاس  AppCompatDelegate  ممکن می شود. دو متد دیگر برای پیاده سازی این تنظیمات وجود دارند که deprecate یا منسوخ شده اند. (MODE_NIGHT_AUTO_TIME وMODE_NIGHT_AUTO)

گزینه ی انتخابی کاربر در shared preferences ذخیره می شود. در فرگمنت یا دیالوگ فرگمنتی که قسمت تنظیمات را مدیریت می کند، متد setTheme را تعریف می کنیم.

private fun setTheme(mode: Int) {
    AppCompatDelegate.setDefaultNightMode(mode)
}

setDefaultNightMode متد استاتیکی در کلاس AppCompatDelegate است که برای فعال نمودن تم تاریک استفاده شده است. همان طور که گفته شد باید این تنظیمات در جایی خارج از چرخه زندگی برنامه ذخیره شود تا در هر باری که برنامه شروع به کار می کند آخرین تنظیم اجرا شود. برای این منظور باید از shared preferences استفاده کرد.

private fun initTheme() {
    val preferences = PreferenceManager.getDefaultSharedPreferences(this)
    ThemeManager.applyTheme(preferences.getString("preference_key_theme", "")!!)
}

از چنین مسیری کلاس ThemeManager  مقدار ذخیره شده را از shared preferences می خواند و با استفاده از آن تم را پیاده می سازد.

تغییر تم برای بخشی از برنامه

اگر لازم باشد تم اکتیویتی مشخصی در برنامه تغییر کند، باید فیلد setLocalNightMode  از کلاس AppCompatDelegate’s استفاده و تم مورد نظر انتخاب گردد.

بدیهی ست برای اجرای این حالت باید اکتیویتی مربوطه از کلاس AppCompatActivity ارث بری کند.

چک نمودن تم فعلی برنامه در کلاس ها به شکل زیر است :

getResources().getConfiguration().uiMode
        & Configuration.UI_MODE_NIGHT_MASK

به این ترتیب به وضعیت فعلی UI دسترسی دارید و می توانید با بررسی نتیجه آن عمل مورد نظر را در برنامه پیاده کنید.

نتیجه گیری

پیاده سازی تم تاریک بعنوان تم اصلی برنامه روشی مستقیم و ساده دارد. اما ممکن است در برنامه نیاز به استفاده از تم تیره در آیکون، webView، نقشه، lottie animations (که به کارگیری رنگ در آنها از resource های برنامه نیست و تامین رنگ ها مشخصات داینامیکی هستند که در لحظه اجرا از سرور با فرمت json گرفته می شوند.)، نوتیفیکیشن ها و مواردی از این دست باشد. هر کدام از این موارد نیز راهی ساده دارند که در صورت تمایل شما مخاطبان عزیز می تواند موضوع مقالات بعدی بلاگ باشد.

 

جهت دسترسی به سورس کامل برنامه pdf خوان که در این مقاله نحوه پیاده سازی تم تاریک را در آن دیدیم، می توانید برای خرید سورس به gitigit_support@ در تلگرام گیتی گیت یا ایمیل آدرس najandchemiker@gmail.com  پیام دهید.

توجه داشته باشید برای پیاده سازی این پروژه از معماری MVVM استفاده شده است. اگر با این معماری آشنایی ندارید می توانید به مقاله پیاده سازی MVVM مراجعه نمایید.

هم چنین از کتابخانه Koin برای تزریق وابستگی نیز استفاده شده که ضرورتی برای یادگیری آن در این پروژه وجود ندارد.

 

 

به این پست امتیاز دهید

روی ستاره های کلیک کنید و امتیاز بدید

میانگین امتیاز / 5. تعداد:

دیدگاهتان را بنویسید

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




Enter Captcha Here : *

Reload Image