Android Styles and Themes
Android styles allow you to design the appearance (for example, colors, size, and fonts) of Android UI components from XML resource files. With this method, you only need to set the common style attribute once in the central location.
This is commonly used to reduce style redundancy in a way that is very similar to CSS in the world of web development. You can specify a style for a single central file to apply a consistent style to the entire view of your application.
Style along with the drawable is a way that helps you to easily keep the face of heavy UI customization. Styles work by declaring a style name accompanied by a set of attributes that you apply to a view. Styles can create compound styles that can be inherited from other styles.
Declaring and using Styles
First, you declare the XML style in res/values/styles.xml directory:
<style name ="ExtraLargeBlueFont">
<item name ="android:textColor">#FF6200EE</item>
<item name ="android:textSize">50sp</item>
</style>
For using styles inside the activity:
<TextView
android:id ="@+id/display_app_name"
style ="@style/ExtraLargeBlueFont"
android:layout_width ="wrap_content"
android:layout_height ="match_parent"
android:text ="@string/app_name" />
Inheritance in Styles
You may want to inherit a style and change certain attributes most of the time. You can specify a style from which your style should inherit properties in the parent attribute of <style> tag. You can use it to inherit properties from existing styles and declare only those properties that you want to modify or add.
<style name ="SmallFont">
<item name ="android:textSize">15sp</item>
</style>
<style name ="SmallPurpleFont" parent="@style/SmallFont">
<item name ="android:textColor">#FF6200EE</item>
</style>
You don't even need to use parent attribute if you choose to inherit from a style, you declare yourself. Instead, simply put the name of the new style, separated by a period, before the name of the inherited style as a shortcut.
<style name ="SmallFont">
<item name ="android:textSize">15sp</item>
</style>
<style name ="SmallFont.Purple">
<item name ="android:textColor">#FF6200EE</item>
</style>
Using multiple periods, you can continue to inherit styles:
<style name ="SmallFont.Purple.Italic">
<item name ="android:textStyle">italic</item>
</style>
<style name ="SmallFont.Purple.Large">
<item name ="android:textSize">40sp</item>
</style>
Android built-in styles cannot be inherited in this manner. You need to use parent attribute to refer a built-in style:
<style name="CustomisedButton" parent="@android:style/Widget.Button">
<item name="android:gravity">top</item>
<item name="android:textColor">#FF6200EE</item>
</style>
Using Themes
Sometimes, we try to apply a consonant theme to all activities in the application. Instead of applying styles to specific individual views, you can apply style collections i.e., themes to your activities or applications. That way, you'll apply each attribute that the activity or all views in your application support.
Declaring a Theme
<style name="LightTheme.MyApplication" parent="Theme.AppCompat.Light">
...
</style>
This theme contains item attributes that often refer to various other styles or colors:
<style name ="LightTheme.MyApplication" parent ="Theme.AppCompat.Light">
<item name ="android:windowBackground">@color/teal_200</item>
<item name ="android:colorBackground">@color/teal_200</item>
</style>
Modifying Themes
In many cases, you might want to modify the default presentation of your application’s views. For example, you can modify the text color of a TextView or Button as the application’s default. It can be accomplished by declaring the styles that are inherited by default, and you can override that property in res / values / styles.xml.
<!-- Base application theme. -->
<style name ="Theme.MyApplication" parent ="Theme.MaterialComponents.DayNight.DarkActionBar">
<!-- Primary brand color. -->
<item name ="colorPrimary">@color/purple_500</item>
<item name ="colorPrimaryVariant">@color/purple_700</item>
<item name ="colorOnPrimary">@color/white</item>
<!-- Secondary brand color. -->
<item name ="colorSecondary">@color/teal_200</item>
<item name ="colorSecondaryVariant">@color/teal_700</item>
<item name ="colorOnSecondary">@color/black</item>
<!-- Status bar color. -->
<item name ="android:statusBarColor" tools:targetApi ="l">?attr/colorPrimaryVariant</item>
<!-- Customize your theme here. -->
<!-- TextView custom theme. -->
<style name ="Widget.TextView.Custom" parent="android:Widget.TextView">
<item name="android:textColor">@color/teal_200</item>
</style>
</style>
Use the generated AppTheme to modify the buttonStyle and textViewStyle to determine the default style for the control. Then inherit from the basic Widget.Button or Widget.TextView and modify it.
Apply Theme
To set the theme for all your application's activities, open the AndroidManifest.xml file and edit the application's tag to add the android: theme attribute in the company with the style name. Example:
<application android:theme ="@style/LightTheme.MyApplication">
You can also apply the theme to a specific activity by adding the following attribute:
<activity android:theme ="@style/LightTheme.MyApplication">
Referencing Styles from Themes
Using the ?attr syntax you can refer the currently applied attribute once a theme is applied. For example, to set the EditText base color to use the default base color, you can do it as follows:
<TextView
android:textColor ="?attr/colorAccent"
android:layout_width ="match_parent"
android:layout_height ="wrap_content"
android:text ="Hello Everyone"/>
Custom theme attributes can also be utilized for button states using state lists:
<selector xmlns:android ="http://schemas.android.com/apk/res/android">
<item android:color ="?attr/colorTeal" android:state_enabled ="false"/>
<item android:color ="?attr/colorSecondary"/>
</selector>
Be sure to utilize the AppCompatResources or ContextCompat helper classes to resolve these theme attributes properly:
ContextCompat.getColor(this, R.color.design_default_color_on_primary);
// resolve the default color
ColorStateList colorState = AppCompatResources.getColorStateList(this, R.color.design_default_color_primary).getDefaultColor();
You should also do the same for drawable as above to allow the theme attributes to be resolved:
Drawable drawable = AppCompatResources.getDrawable(this, R.drawable.ic_baseline_arrow_drop_down_24);