استایلها و تمها در اندروید به شما این امکان را میدهند که جزئیات طراحی برنامه خود را از ساختار و رفتار رابط کاربری جدا کنید، مشابه stylesheets در طراحی وب.
یک استایل مجموعهای از ویژگیها است که ظاهر یک View را مشخص میکند. یک استایل میتواند ویژگیهایی مانند رنگ فونت، اندازه فونت، رنگ پسزمینه و موارد دیگر را مشخص کند.
یک تم مجموعهای از ویژگیها است که به کل سلسله مراتب برنامه، فعالیت یا نمایش اعمال میشود - نه فقط به یک نمای خاص. وقتی یک تم را اعمال میکنید، هر نمای موجود در برنامه یا فعالیت، هر یک از ویژگیهای تم را که پشتیبانی میکند، اعمال میکند. تمها همچنین میتوانند سبکها را به عناصر غیر نمایشی، مانند نوار وضعیت و پسزمینه پنجره، اعمال کنند.
استایلها و تمها در یک فایل منبع استایل در res/values/ تعریف میشوند که معمولاً styles.xml نام دارد.

شکل ۱. دو تم که روی یک اکتیویتی اعمال شدهاند: Theme.AppCompat (چپ) و Theme.AppCompat.Light (راست).
تمها در مقابل سبکها
تمها و استایلها شباهتهای زیادی دارند، اما برای اهداف متفاوتی استفاده میشوند. تمها و استایلها ساختار اساسی یکسانی دارند - یک جفت کلید-مقدار که ویژگیها را به منابع نگاشت میکند.
یک سبک، ویژگیهایی را برای نوع خاصی از نما مشخص میکند. برای مثال، یک سبک ممکن است ویژگیهای یک دکمه را مشخص کند. هر ویژگی که در یک سبک مشخص میکنید، ویژگیای است که میتوانید در فایل طرحبندی تنظیم کنید. استخراج تمام ویژگیها به یک سبک، استفاده و نگهداری آنها را در چندین ویجت آسان میکند.
یک تم مجموعهای از منابع نامگذاری شده را تعریف میکند که میتوانند توسط استایلها، طرحبندیها، ویجتها و غیره مورد ارجاع قرار گیرند. تمها نامهای معنایی مانند colorPrimary را به منابع اندروید اختصاص میدهند.
استایلها و تمها قرار است با هم کار کنند. برای مثال، ممکن است استایلی داشته باشید که مشخص کند یک قسمت از یک دکمه colorPrimary و قسمت دیگر colorSecondary باشد. تعاریف واقعی آن رنگها در تم ارائه شده است. وقتی دستگاه به حالت شب میرود، برنامه شما میتواند از تم "روشن" به تم "تاریک" تغییر کند و مقادیر همه آن نامهای منبع را تغییر دهد. نیازی به تغییر استایلها ندارید، زیرا استایلها از نامهای معنایی استفاده میکنند و نه تعاریف خاص رنگ.
برای اطلاعات بیشتر در مورد نحوهی همکاری تمها و استایلها، به پست وبلاگ «استایلبندی اندروید: تمها در مقابل استایلها» مراجعه کنید.
ایجاد و اعمال یک سبک
برای ایجاد یک سبک جدید، فایل res/values/styles.xml پروژه خود را باز کنید. برای هر سبکی که میخواهید ایجاد کنید، این مراحل را دنبال کنید:
- یک عنصر
<style>با نامی که به طور منحصر به فرد سبک را مشخص میکند، اضافه کنید. - برای هر ویژگی استایلی که میخواهید تعریف کنید، یک عنصر
<item>اضافه کنید.nameهر آیتم، ویژگیای را مشخص میکند که در غیر این صورت به عنوان یک ویژگی XML در طرحبندی خود استفاده خواهید کرد. مقدار موجود در عنصر<item>، مقدار آن ویژگی است.
برای مثال، فرض کنید استایل زیر را تعریف کردهاید:
<?xml version="1.0" encoding="utf-8"?> <resources> <style name="GreenText" parent="TextAppearance.AppCompat"> <item name="android:textColor">#00FF00</item> </style> </resources>
شما میتوانید این استایل را به صورت زیر به یک نما اعمال کنید:
<TextView style="@style/GreenText" ... />
هر ویژگی مشخص شده در استایل، در صورتی که نما آن را بپذیرد، به آن اعمال میشود. نما، هر ویژگیای را که نپذیرد، نادیده میگیرد.
با این حال، به جای اعمال یک سبک به نماهای منفرد، معمولاً سبکها را به عنوان یک تم برای کل برنامه، فعالیت یا مجموعهای از نماها اعمال میکنید ، همانطور که در بخش دیگری از این راهنما توضیح داده شده است.
گسترش و سفارشیسازی یک سبک
هنگام ایجاد استایلهای خودتان، همیشه یک استایل موجود را از چارچوب یا کتابخانه پشتیبانی گسترش دهید تا سازگاری با استایلهای رابط کاربری پلتفرم حفظ شود. برای گسترش یک استایل، استایلی را که میخواهید گسترش دهید با ویژگی parent مشخص کنید. سپس میتوانید ویژگیهای استایل ارثبری شده را نادیده بگیرید و موارد جدیدی اضافه کنید.
برای مثال، میتوانید ظاهر متن پیشفرض پلتفرم اندروید را به ارث ببرید و آن را به صورت زیر تغییر دهید:
<style name="GreenText" parent="@android:style/TextAppearance"> <item name="android:textColor">#00FF00</item> </style>
با این حال، همیشه استایلهای اصلی برنامه خود را از کتابخانه پشتیبانی اندروید (Android Support Library) به ارث ببرید. استایلهای موجود در کتابخانه پشتیبانی با بهینهسازی هر استایل برای ویژگیهای رابط کاربری موجود در هر نسخه، سازگاری را فراهم میکنند. استایلهای کتابخانه پشتیبانی اغلب نامی مشابه استایل پلتفرم دارند، اما AppCompat نیز در آنها گنجانده شده است.
برای به ارث بردن استایلها از یک کتابخانه یا پروژه خودتان، نام استایل والد را بدون قسمت @android:style/ که در مثال قبلی نشان داده شده است، اعلان کنید. برای مثال، مثال زیر استایلهای ظاهر متن را از کتابخانه پشتیبانی به ارث میبرد:
<style name="GreenText" parent="TextAppearance.AppCompat"> <item name="android:textColor">#00FF00</item> </style>
همچنین میتوانید سبکها - به جز سبکهای پلتفرم - را با اضافه کردن نام سبک با علامت نقطه، به جای استفاده از ویژگی parent ، به ارث ببرید. یعنی، نام سبک خود را با نام سبکی که میخواهید به ارث ببرید، پیشوند دهید و با یک نقطه از هم جدا کنید. معمولاً این کار را فقط هنگام اضافه کردن سبکهای خودتان انجام میدهید، نه سبکهای کتابخانههای دیگر. به عنوان مثال، سبک زیر تمام سبکها را از GreenText در مثال قبلی به ارث میبرد و سپس اندازه متن را افزایش میدهد:
<style name="GreenText.Large"> <item name="android:textSize">22dp</item> </style>
شما میتوانید با اضافه کردن نامهای بیشتر، هر چند بار که بخواهید، به ارث بردن استایلهایی مانند این ادامه دهید.
برای یافتن ویژگیهایی که میتوانید با برچسب <item> اعلان کنید، به جدول "ویژگیهای XML" در ارجاعات کلاسهای مختلف مراجعه کنید. همه نماها از ویژگیهای XML کلاس پایه View پشتیبانی میکنند و بسیاری از نماها ویژگیهای خاص خود را اضافه میکنند. به عنوان مثال، ویژگیهای XML مربوط به TextView شامل ویژگی android:inputType است که میتوانید آن را به یک نمای متنی که ورودی دریافت میکند، مانند یک ویجت EditText ، اعمال کنید.
اعمال یک سبک به عنوان یک تم
شما میتوانید یک تم را به همان روشی که استایلها را ایجاد میکنید، ایجاد کنید. تفاوت در نحوه اعمال آن است: به جای اعمال یک استایل با ویژگی style در یک نما، یک تم را با ویژگی android:theme یا در تگ <application> یا در تگ <activity> در فایل AndroidManifest.xml اعمال میکنید.
برای مثال، در اینجا نحوه اعمال تم «تاریک» طراحی متریال کتابخانه پشتیبانی اندروید به کل برنامه آورده شده است:
<manifest ... > <application android:theme="@style/Theme.AppCompat" ... > </application> </manifest>
و در اینجا نحوه اعمال تم "روشن" فقط برای یک فعالیت آورده شده است:
<manifest ... > <application ... > <activity android:theme="@style/Theme.AppCompat.Light" ... > </activity> </application> </manifest>
هر ویو در برنامه یا اکتیویتی، استایلهایی را که از استایلهای تعریفشده در تم دادهشده پشتیبانی میکند، اعمال میکند. اگر ویو فقط از برخی از ویژگیهای اعلامشده در استایل پشتیبانی کند، فقط آن ویژگیها را اعمال میکند و آنهایی را که پشتیبانی نمیکند، نادیده میگیرد.
از اندروید ۵.۰ (API سطح ۲۱) و کتابخانه پشتیبانی اندروید نسخه ۲۲.۱، میتوانید ویژگی android:theme را به یک نما در فایل طرحبندی خود نیز مشخص کنید. این کار، تم آن نما و هر نمای فرزند را تغییر میدهد که برای تغییر پالتهای رنگ تم در بخش خاصی از رابط کاربری شما مفید است.
مثالهای قبلی نحوهی اعمال یک تم مانند Theme.AppCompat که توسط کتابخانهی پشتیبانی اندروید ارائه شده است را نشان میدهند. با این حال، شما معمولاً میخواهید تم را متناسب با برند برنامهی خود سفارشی کنید. بهترین راه برای انجام این کار، گسترش این استایلها از کتابخانهی پشتیبانی و لغو برخی از ویژگیها است، همانطور که در بخش بعدی توضیح داده شده است.
سلسله مراتب سبک
اندروید روشهای متنوعی برای تنظیم ویژگیها در سراسر برنامه اندروید شما ارائه میدهد. برای مثال، میتوانید ویژگیها را مستقیماً در یک طرحبندی تنظیم کنید، یک سبک را به یک نما اعمال کنید، یک تم را به یک طرحبندی اعمال کنید و حتی ویژگیها را به صورت برنامهنویسی تنظیم کنید.
هنگام انتخاب نحوهی استایلدهی به برنامهی خود، به سلسله مراتب استایل اندروید توجه داشته باشید. به طور کلی، برای حفظ ثبات، تا حد امکان از تمها و استایلها استفاده کنید. اگر ویژگیهای یکسانی را در چندین جا مشخص کنید، لیست زیر تعیین میکند که در نهایت کدام ویژگیها اعمال شوند. این لیست از بالاترین اولویت به پایینترین اولویت مرتب شده است.
- اعمال سبکدهی در سطح کاراکتر یا پاراگراف با استفاده از spanهای متنی به کلاسهای مشتق شده از
TextView. - اعمال ویژگیها به صورت برنامهنویسیشده
- اعمال مستقیم ویژگیهای منحصر به فرد به یک نما.
- اعمال یک سبک به یک نما.
- استایل پیشفرض.
- اعمال یک تم به مجموعهای از ویوها، یک اکتیویتی یا کل برنامه شما.
- اعمال استایلبندی خاص برای نما، مانند تنظیم
TextAppearanceروی یکTextView.

شکل ۲. استایلدهی از یک span ، استایلدهی از یک textAppearance را لغو میکند.
ظاهر متن
یکی از محدودیتهای استایلها این است که فقط میتوانید یک استایل را به یک View اعمال کنید. با این حال، در یک TextView ، میتوانید یک ویژگی TextAppearance نیز تعیین کنید که عملکردی مشابه با یک استایل داشته باشد، همانطور که در مثال زیر نشان داده شده است:
<TextView ... android:textAppearance="@android:style/TextAppearance.Material.Headline" android:text="This text is styled via textAppearance!" />
TextAppearance به شما امکان میدهد سبکبندی مختص متن را تعریف کنید، در حالی که سبک یک View را برای سایر کاربردها در دسترس قرار میدهد. با این حال، توجه داشته باشید که اگر هرگونه ویژگی متنی را مستقیماً در View یا در یک style تعریف کنید، آن مقادیر، مقادیر TextAppearance را نادیده میگیرند.
TextAppearance از زیرمجموعهای از ویژگیهای استایلبندی که TextView ارائه میدهد، پشتیبانی میکند. برای مشاهدهی لیست کامل ویژگیها، به TextAppearance مراجعه کنید.
برخی از ویژگیهای رایج TextView که شامل نمیشوند عبارتند از lineHeight[Multiplier|Extra] ، lines ، breakStrategy و hyphenationFrequency . TextAppearance در سطح کاراکتر کار میکند و نه در سطح پاراگراف، بنابراین ویژگیهایی که بر کل طرحبندی تأثیر میگذارند پشتیبانی نمیشوند.
سفارشیسازی تم پیشفرض
وقتی با اندروید استودیو یک پروژه ایجاد میکنید، اندروید استودیو به طور پیشفرض یک تم طراحی متریال (Material Design) را به برنامه شما اعمال میکند، همانطور که در فایل styles.xml پروژه شما تعریف شده است. این استایل AppTheme یک تم از کتابخانه پشتیبانی (Support Library) را بسط میدهد و شامل overrideهایی برای ویژگیهای رنگی است که توسط عناصر کلیدی رابط کاربری، مانند نوار برنامه و دکمه اکشن شناور (در صورت استفاده) استفاده میشوند. بنابراین، میتوانید با بهروزرسانی رنگهای ارائه شده، به سرعت طراحی رنگ برنامه خود را سفارشی کنید.
برای مثال، فایل styles.xml شما چیزی شبیه به این است:
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar"> <!-- Customize your theme here. --> <item name="colorPrimary">@color/colorPrimary</item> <item name="colorPrimaryDark">@color/colorPrimaryDark</item> <item name="colorAccent">@color/colorAccent</item> </style>
مقادیر استایل در واقع ارجاعاتی به سایر منابع رنگ هستند که در فایل res/values/colors.xml پروژه تعریف شدهاند. این فایلی است که برای تغییر رنگها ویرایش میکنید. برای بهبود تجربه کاربری با رنگهای پویا و رنگهای سفارشی اضافی، به نمای کلی رنگهای طراحی متریال مراجعه کنید.
وقتی رنگهایتان را شناختید، مقادیر موجود در res/values/colors.xml را بهروزرسانی کنید:
<?xml version="1.0" encoding="utf-8"?> <resources> <!-- Color for the app bar and other primary UI elements. --> <color name="colorPrimary">#3F51B5</color> <!-- A darker variant of the primary color, used for the status bar (on Android 5.0+) and contextual app bars. --> <color name="colorPrimaryDark">#303F9F</color> <!-- a secondary color for controls like checkboxes and text fields. --> <color name="colorAccent">#FF4081</color> </resources>
سپس میتوانید هر سبک دیگری را که میخواهید، بازنویسی کنید. برای مثال، میتوانید رنگ پسزمینه فعالیت را به صورت زیر تغییر دهید:
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar"> ... <item name="android:windowBackground">@color/activityBackground</item> </style>
برای مشاهدهی فهرستی از ویژگیهایی که میتوانید در قالب خود استفاده کنید، به جدول ویژگیها در R.styleable.Theme مراجعه کنید. هنگام افزودن سبکها به نماها در طرحبندی خود، میتوانید با مراجعه به جدول "ویژگیهای XML" در ارجاعات کلاس نما، ویژگیها را نیز پیدا کنید. به عنوان مثال، همه نماها از ویژگیهای XML کلاس پایه View پشتیبانی میکنند.
بیشتر ویژگیها به انواع خاصی از نماها اعمال میشوند و برخی از آنها به همه نماها اعمال میشوند. با این حال، برخی از ویژگیهای تم که در R.styleable.Theme فهرست شدهاند، به پنجره فعالیت اعمال میشوند، نه نماهای موجود در طرحبندی. به عنوان مثال، windowBackground پسزمینه پنجره را تغییر میدهد و windowEnterTransition یک انیمیشن انتقال را برای استفاده هنگام شروع فعالیت تعریف میکند. برای جزئیات بیشتر، به Start an activity using an animation مراجعه کنید.
کتابخانه پشتیبانی اندروید همچنین ویژگیهای دیگری را ارائه میدهد که میتوانید برای سفارشیسازی قالب خود که از Theme.AppCompat توسعه داده شده است، استفاده کنید، مانند ویژگی colorPrimary که در مثال قبلی نشان داده شده است. این ویژگیها به بهترین شکل در فایل attrs.xml کتابخانه قابل مشاهده هستند.
همچنین قالبهای مختلفی از کتابخانه پشتیبانی موجود است که ممکن است بخواهید به جای قالبهای نشان داده شده در مثال قبلی، آنها را گسترش دهید. بهترین مکان برای مشاهده قالبهای موجود، فایل themes.xml کتابخانه است.
اضافه کردن استایلهای مخصوص هر نسخه
اگر نسخه جدید اندروید ویژگیهای تم مورد نظر شما را اضافه کند، میتوانید آنها را به تم خود اضافه کنید و در عین حال با نسخههای قدیمی سازگار باشید. تنها چیزی که نیاز دارید یک فایل styles.xml دیگر است که در یک دایرکتوری values ذخیره شده و شامل توصیفگر نسخه منبع باشد:
res/values/styles.xml # themes for all versions res/values-v21/styles.xml # themes for API level 21+ only
از آنجا که استایلهای موجود در فایل values/styles.xml برای همه نسخهها در دسترس هستند، تمهای شما در values-v21/styles.xml میتوانند آنها را به ارث ببرند. این بدان معناست که میتوانید با شروع از یک تم "پایه" و سپس گسترش آن در استایلهای مختص به نسخه خود، از تکرار استایلها جلوگیری کنید.
برای مثال، برای تعریف گذارهای پنجره برای اندروید ۵.۰ (سطح API ۲۱) و بالاتر، باید از ویژگیهای جدید استفاده کنید. بنابراین، قالب پایه شما در res/values/styles.xml میتواند به این شکل باشد:
<resources> <!-- Base set of styles that apply to all versions. --> <style name="BaseAppTheme" parent="Theme.AppCompat.Light.DarkActionBar"> <item name="colorPrimary">@color/primaryColor</item> <item name="colorPrimaryDark">@color/primaryTextColor</item> <item name="colorAccent">@color/secondaryColor</item> </style> <!-- Declare the theme name that's actually applied in the manifest file. --> <style name="AppTheme" parent="BaseAppTheme" /> </resources>
سپس، استایلهای مختص به نسخه را در res/values-v21/styles.xml به صورت زیر اضافه کنید:
<resources> <!-- extend the base theme to add styles available only with API level 21+ --> <style name="AppTheme" parent="BaseAppTheme"> <item name="android:windowActivityTransitions">true</item> <item name="android:windowEnterTransition">@android:transition/slide_right</item> <item name="android:windowExitTransition">@android:transition/slide_left</item> </style> </resources>
حالا میتوانید AppTheme در فایل مانیفست خود اعمال کنید و سیستم استایلهای موجود برای هر نسخه سیستم را انتخاب میکند.
برای اطلاعات بیشتر در مورد استفاده از منابع جایگزین برای دستگاههای مختلف، به ارائه منابع جایگزین مراجعه کنید.
سفارشی سازی سبک های ویجت
هر ویجت در چارچوب و کتابخانه پشتیبانی دارای یک سبک پیشفرض است. برای مثال، وقتی برنامه خود را با استفاده از یک تم از کتابخانه پشتیبانی سبکبندی میکنید، یک نمونه از Button با استفاده از سبک Widget.AppCompat.Button سبکبندی میشود. اگر میخواهید سبک ویجت متفاوتی را به یک دکمه اعمال کنید، میتوانید این کار را با ویژگی style در فایل طرحبندی خود انجام دهید. برای مثال، کد زیر سبک دکمه بدون حاشیه کتابخانه را اعمال میکند:
<Button style="@style/Widget.AppCompat.Button.Borderless" ... />
اگر میخواهید این استایل را روی همه دکمهها اعمال کنید، میتوانید آن را در buttonStyle قالب خود به صورت زیر تعریف کنید:
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar"> <item name="buttonStyle">@style/Widget.AppCompat.Button.Borderless</item> ... </style>
شما همچنین میتوانید استایلهای ویجت را مانند هر استایل دیگری گسترش دهید و سپس استایل ویجت سفارشی خود را در طرحبندی یا قالب خود اعمال کنید.
منابع اضافی
برای آشنایی بیشتر با تمها و سبکها، به منابع اضافی زیر مراجعه کنید:
پستهای وبلاگ
- استایلبندی اندروید: تمها در مقابل استایلها
- استایلبندی اندروید: ویژگیهای رایج تم
- استایل اندروید: ویژگیهای قالب را ترجیح دهید
