۱. قبل از شروع
در این آزمایشگاه کد، شما برنامهی آغازین، یک برنامهی محاسبهی انعام، را بهروزرسانی خواهید کرد تا از ویژگیهای جدید طراحی متریال ۳ استفاده کند که به رابط کاربری برنامه اجازه میدهد تا به صورت پویا بر اساس تصویر زمینهی کاربر، تمبندی شود. در زیر چند تصویر از برنامه با رنگ پویای اعمال شده، آورده شده است. همچنین چند سناریوی اضافی را بررسی خواهید کرد که به شما امکان کنترل نحوهی اعمال رنگها را میدهد.
پیشنیازها
توسعهدهندگان باید باشند
- آشنایی با مفاهیم اولیه تم گذاری در اندروید
- با تغییر تم برنامه راحت است
آنچه یاد خواهید گرفت
- چگونه بین کامپوننتهای متریال موجود و قالبهای متریال ۳ تمایز قائل شویم
- نحوه بهروزرسانی یک قالب به متریال ۳
- نحوه ایجاد تمها با استفاده از ابزارهای ما و اعمال آنها
- چگونه ویژگیهای قالب با یکدیگر مرتبط میشوند
آنچه نیاز دارید
- کامپیوتری که اندروید استودیو روی آن نصب شده باشد.
- کد مربوط به اپلیکیشن Tip Time. https://github.com/google-developer-training/android-basics-kotlin-tip-calculator-app-solution
۲. بررسی اجمالی برنامهی آغازین
اپلیکیشن Tip Time یک اپلیکیشن محاسبهگر انعام با گزینههایی برای سفارشیسازی انعام است. این یکی از اپلیکیشنهای نمونه از دوره آموزشی Android Basics in Kotlin ما است.

۳. بهروزرسانی وابستگیهای Gradle
قبل از اینکه قالب اصلی را بهروزرسانی کنیم و رنگ پویا را اعمال کنیم، چند تغییر وجود دارد که باید در فایل build.gradle برنامه شما اعمال شود.
در بخش وابستگیها، مطمئن شوید که کتابخانه مواد ۱.۵.۰-alpha04 یا بالاتر است:
dependencies {
// ...
implementation 'com.google.android.material:material:<version>'
}
در بخش اندروید، compileSdkVersion و targetSdkVersion را تغییر دهید.
تا ۳۱ یا بالاتر:
android {
compileSdkVersion 31
// ...
defaultConfig {
// ...
targetSdkVersion 31
}
}
این دستورالعملها فرض را بر این میگذارند که برنامهای با وابستگیهای نسبتاً جدید وجود دارد. برای برنامهای که از قبل از Material استفاده نمیکند یا نسخه جدیدتری دارد، لطفاً دستورالعملهای موجود در مستندات شروع به کار کامپوننتهای طراحی متریال برای اندروید را بررسی کنید.
هر جا که قالبهای خود را ایجاد کردهاید، ارجاعات Theme.MaterialComponents.* را به Theme.Material3.* تغییر دهید. برخی از استایلها هنوز استایل جدیدی در فضای نام Material3 ندارند، اما اکثر کامپوننتها پس از بهروزرسانی قالب والد به Theme.Material3.* ، همچنان استایل جدید را به ارث میبرند. در زیر میتوانیم ببینیم که دکمهها اکنون قالب گرد جدید را به خود میگیرند.
در فایل تمهای زیر، تنها چیزی که تغییر کرده، تم والد است. ما به زودی این تم را به طور کامل جایگزین خواهیم کرد. برخی از ویژگیهای رنگ منسوخ شدهاند و برخی از سبکهای سفارشی که ایجاد کردهایم، اکنون در Material3 استاندارد هستند، اما میخواستیم شما آنها را داشته باشید.
تمها.xml
<style name="Theme.TipTime" parent="Theme.Material3.Light">
<!-- Primary brand color. -->
<item name="colorPrimary">@color/green</item>
<item name="colorPrimaryVariant">@color/green_dark</item>
<item name="colorOnPrimary">@color/white</item>
<!-- Secondary brand color. -->
<item name="colorSecondary">@color/blue</item>
<item name="colorSecondaryVariant">@color/blue_dark</item>
<item name="colorOnSecondary">@color/black</item>
<!-- Status bar color. -->
<item name="android:statusBarColor" tools:targetApi="l">?attr/colorPrimaryVariant</item>
<!-- For text input fields -->
<item name="textInputStyle">@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox</item>
<!-- For radio buttons -->
<item name="radioButtonStyle">@style/Widget.TipTime.CompoundButton.RadioButton</item>
<!-- For switches -->
<item name="switchStyle">@style/Widget.TipTime.CompoundButton.Switch</item>
</style>

۴. درک تم رنگی و نقشهای رنگی
سیستم رنگ Material 3 از یک رویکرد سازمانیافته برای اعمال رنگها به رابط کاربری شما استفاده میکند. تعدادی از ویژگیهای Theme.AppCompat هنوز در حال استفاده هستند. با این حال، ویژگیهای بیشتری در Theme.MaterialComponents.* و حتی موارد بیشتری در Theme.Material3.* اضافه شدهاند، بنابراین بررسی تمام صفحات برنامه شما برای اطمینان از اینکه هیچ ویژگی پیادهسازی نشدهای از تم پایه به بیرون درز نکرده باشد، مهم است.
درک نقشهای رنگ
بیش از بیست ویژگی مرتبط با رنگ در قالب Material 3 وجود دارد. این ممکن است در ابتدا دلهرهآور به نظر برسد، اما در واقع چند رنگ کلیدی وجود دارد که با همان ۴-۵ نقش رنگی ترکیب میشوند تا رنگهای مشتق شده را ایجاد کنند.
آن گروههای رنگی عبارتند از:
- رنگ اصلی، رنگ اصلی برنامه شما
- ثانویه، رنگ ثانویه برنامه شما
- رنگ ثالثیه، یا رنگ سومی که مکمل رنگ اولیه و ثانویه است
- خطا، برای متن خطا و دیالوگها استفاده میشود.
- پیشینه
- سطح، متغیر سطح، معکوس سطح
نقشها برای اولیه، ثانویه، ثالثیه و خطا به شرح زیر است:
<رنگ پایه> | رنگ پایه |
روشن<رنگ پایه> | رنگ آیکونها و متنی که روی رنگ پایه ظاهر میشوند |
<رنگ پایه>کانتینر | مشتق شده از پایه، رنگ، مورد استفاده برای دکمهها، کادرهای گفتگو و غیره |
روی<رنگ پایه>کانتینر | رنگ آیکونها و متن روی کانتینر |
برای مثال، یک دکمهی عملیاتی شناور با استایل پیشفرض در متریال ۳ از رنگ Primary به عنوان رنگ پایه خود استفاده میکند، بنابراین primaryContainer برای رنگ پسزمینهی دکمه و onPrimaryContainer برای محتوای آن استفاده میکند.
هنگام سفارشیسازی دستی یک قالب، حداقل باید تأیید کنید که ویژگی on<base color> برای هر رنگ پایهای که تغییر میدهید، همچنان خوانا باشد.
بهترین روشها این است که تمام نقشها را در یک گروه رنگی به طور همزمان تنظیم کنید تا از عدم وجود هرگونه تغییر غیرطبیعی از پایه تا برنامه شما اطمینان حاصل شود.
رنگهای پایه پسزمینه و سطح عموماً دو نقش دارند، یکی برای خود on<base color> برای آیکونها یا متنی که روی آن ظاهر میشود.
۵. ایجاد یک قالب متریال ۳ با استفاده از Material Theme Builder
سازندهی تم متریال، ساخت طرح رنگی سفارشی را آسان میکند، از خروجی کد داخلی آن برای مهاجرت به سیستم رنگ M3 استفاده کنید و از رنگ پویا بهره ببرید. اطلاعات بیشتر در material.io/material-theme-builder
تم برنامه Tip Time شامل چندین استایل برای کامپوننتها است، با این حال بیشتر استایلها در تمهای Material 3 پیشفرض هستند. تنها دو رنگ کلیدی که باید به آنها توجه کنیم، رنگهای اصلی و فرعی هستند.
این رنگها مربوط به یک رنگ اصلی سبز (#1B5E20) و یک رنگ فرعی آبی (#0288D1) هستند.
شما میتوانید این رنگها را در سازندهی تم متریال وارد کنید و یک تم کامل را خروجی بگیرید (با فرض اینکه لینکی به یک نمای کلی کامل در جای دیگری وجود دارد).
توجه داشته باشید که رنگهایی که وارد میکنید ممکن است برای تطبیق با الگوریتم تولید رنگ و اطمینان از رنگهای مکمل و خوانا، از نظر تُن تغییر کنند.
در زیر زیرمجموعهای از مقادیری که هنگام وارد کردن رنگهای سفارشی ایجاد میشوند، آمده است.

۶. کار با فایلهای خروجی سازنده قالب متریال
آرشیو خروجی شامل دایرکتوریهای values و values-night/ با فایل themes.xml مخصوص به خود است که مربوط به تمهای روشن و تیره است. همه رنگها در values/colors.xml تعریف شدهاند.

فایلها را میتوان به همین شکل کپی کرد، اما باید نام قالب خود را AndroidManifest.xml یا در فایلهای قالب تغییر دهید تا با یکدیگر مطابقت داشته باشند. نام پیشفرض tooling، AppTheme است.
برنامه را مجدداً راهاندازی کنید و تقریباً دقیقاً یکسان به نظر میرسد. یکی از تغییرات قابل توجه، دکمههای Switch و RadioButtons است که حالتهای انتخابی آنها اکنون با تُنهایی از رنگ اصلی در مقابل رنگهای ثانویه تنظیم شدهاند. در برنامههای بزرگتر، ممکن است مجبور شوید برخی از طرحها را دوباره بررسی کنید.

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.tiptime">
<application ...>
<activity android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
۷. افزودن رنگ پویا
با استفاده از یک تم مناسب Material 3، میتوانیم با اضافه کردن چند نکته کوچک، رابط کاربری را پویا کنیم.
API رنگهای پویا به شما امکان میدهد رنگ پویا را به همه فعالیتها اعمال کنید.
در یک برنامه، فعالیتهای منفرد، یا به نماها یا قطعات منفرد. برای
در این برنامه، ما رنگ پویا را به صورت سراسری اعمال خواهیم کرد.
ایجاد فایل کلاس Application
class TipTimeApplication: Application() {
override fun onCreate() {
// Apply dynamic color
DynamicColors.applyToActivitiesIfAvailable(this)
}
}
ما باید این فایل تازه ایجاد شده را در مانیفست اندروید ارجاع دهیم:
فایل AndroidManifest.xml
< application android name=".TipTimeApplication
<!--- Other existing attributes –>
</application >
در سیستمهای اندروید ۱۲+، طرح پیشفرض کاغذ دیواری کاربر (طرح زمینه) برای تولید چندین پالت رنگی بررسی میشود. مقادیر این پالتها برای ایجاد یک ThemeOverlay استفاده میشوند.
کلاس DynamicColors یک ActivityLifecycleCallbacks ثبت میکند که ActivityPreCreated را رهگیری میکند تا پوستهی پویای ایجاد شده توسط سیستم یا پوستهای که شما ارائه کردهاید را اعمال کند.

۸. اعمال یک پوسته سفارشی
ابزار ما میتواند پوستههای قالب را صادر کند، اما اگر تعداد کمی از ویژگیها را نادیده بگیرید، میتوانید آنها را به صورت دستی نیز ایجاد کنید.
یک پوستهی رویی (یا پوستهی همپوشان) برای استفاده در کنار پوستهی دیگر طراحی شده است و فقط مقادیری را ارائه میدهد که روی پوستهی پایه تغییر خواهند کرد.
بیایید فرض کنیم که به دلایلی، شاید برای برندسازی، نیاز داریم که تُنهای رنگ اصلی، سایههایی از قرمز باشند. میتوانیم این کار را با فایلها و ویژگیهای زیر انجام دهیم.
رنگها.xml
<resources>
<color name="overlay_light_primary">#9C4146</color>
<color name="overlay_light_onPrimary">#FFFFFF</color>
<color name= "overlay_light_primaryContainer">#FFDADB</color>
<color name="overlay_light_onPrimaryContainer">#400008</color>
</resources >
themes_overlays.xml
<style name="AppTheme.Overlay" parent="ThemeOverlay.Material3.DynamicColors.Light">
<item name="colorPrimary">@color/overlay_light_primary</item>
<item name="colorOnPrimary">@color/overlay_light_onPrimary</item>
<item name="colorPrimaryContainer">@color/overlay_light_primaryContainer</item>
<item name="colorOnPrimaryContainer">@color/overlay_light_onPrimaryContainer<item>
</style>
برای کد بالا، اندروید ۱۲ یک تم روشن پویا اعمال میکند و تغییرات شما را روی آن قرار میدهد. به عنوان یک جایگزین، میتوانید از هر ThemeOverlay معتبری به عنوان والد، از جمله هر یک از موارد زیر، استفاده کنید:
ThemeOverlay.Material3.Light
ThemeOverlay.Material3.Dark
ThemeOverlay.Material3.DayNight ThemeOverlay.Material3.DynamicColors.Dark
ThemeOverlay.Material3.DynamicColors.DayNight
برای استفاده از این Theme Overlay به جای پیشفرض Material، فراخوانی DynamicColors.applyToActivitiesIfAvailable را به صورت زیر تغییر دهید:
DynamicColors.applyToActivitiesIfAvailable(this, R.style.AppTheme_Overlay)

۹. افزودن رنگ پویا به ویژگیهای سفارشی
تا اینجا ما ویژگیهایی را که از قبل در قالب Material 3 وجود داشتند، لغو کردهایم. یک حالت ممکن دیگر در رنگ پویا داریم که ممکن است یک یا چند ویژگی سفارشی داشته باشیم که باید اختصاص داده شوند.
وقتی یک برنامه از رنگ پویا استفاده میکند، به ۵ پالت تُن دسترسی پیدا میکند - سه پالت رنگهای تأکیدی و دو پالت رنگهای خنثی با نقشهای تقریبی زیر:
system_accent1 | تنالیتههای رنگ اصلی |
system_accent2 | تُنهای رنگ ثانویه |
system_accent3 | تُنهای رنگ ثالثیه |
سیستم_خنثی1 | پسزمینهها و سطوح خنثی |
سیستم_خنثی۲ | سطوح و خطوط خنثی |
هر پالت دارای تعدادی گام تُن است که از سفید شروع میشود.
به مشکی: ۰، ۱۰، ۵۰، ۱۰۰، ۲۰۰، ۳۰۰، ۴۰۰، ۵۰۰، ۶۰۰، ۷۰۰، ۸۰۰، ۹۰۰، ۱۰۰۰.
هنگام طراحی رابط کاربری برای رنگهای پویا، باید کمتر در مورد رنگ خاص و بیشتر در مورد رابطهی تُن و درخشندگی آن جزء با سایر اجزا در سیستم طراحی فکر کنید.
فرض کنید میخواهید آیکونها با استفاده از پالت رنگ ثانویه، تمبندی شوند و یک ویژگی به آیکونهای tint با ورودی زیر در attrs.xml اضافه کردهاید.
attrs.xml
<resources>
<attr name="iconColor" format="color" />
</resources>
پوستهی شما ممکن است چیزی شبیه به این باشد:
<style name="AppTheme.Overlay" parent="ThemeOverlay.Material3.DynamicColors.DayNight">
<item name="iconColor">@android:color/system_accent2_600</item>
</style>
وقتی برنامه را دوباره نصب میکنید و تصویر زمینه خود را تغییر میدهید، برنامه آن پالت رنگ ثانویه را انتخاب میکند.


این پالتها مخصوص اندروید ۱۲ (API 31) هستند، بنابراین باید فایلهای مربوطه را در پوشههایی با پسوند -v31 قرار دهید، مگر اینکه برنامه شما حداقل SDK 31 یا بالاتر داشته باشد.
۱۰. خلاصه
در این آزمایشگاه کد، شما توانستهاید:
- برای ارتقاء قالب خود به Material 3، وابستگیها را اضافه کنید.
- گروهها و نقشهای جدید رنگ را درک کنید.
- نحوه مهاجرت از یک قالب استاتیک به رنگ پویا را درک کنید.
- نحوه استفاده از پوششهای تم و استفاده از رنگ پویا برای ویژگیهای سفارشی تم را درک کنید.