I want all Toolbar
to look the same, without setting styles in all of them,
so I though I would set the app theme for it. One of the things I wanted all them to have is the colorControlNormal
atribute. These were my attempts:
Code sample 1:
<resources>
<style name="MyTheme" parent="Theme.AppCompat.Light.NoActionBar">
<item name="toolbarStyle">@style/MyTheme.ToolbarStyle</item>
</style>
<style name="MyTheme.ToolbarStyle" parent="@style/Widget.AppCompat.Toolbar">
<item name="colorControlNormal">@color/toolbarColorControlNormal</item>
</style>
</resources>
Code sample 2:
<resources>
<style name="MyTheme" parent="Theme.AppCompat.Light.NoActionBar">
<item name="colorControlNormal">@color/toolbarColorControlNormal</item>
</style>
</resources>
In Code sample 1, I tried to create a custom style for the Toolbar
atributes, and set it to the theme, but it didn't work.
In Code sample 2, I set the attribute globally and worked. However, affects other components too, so it's not valid.
I need to change the tabTextColor
and tabSelectedTextColor
attributes of all TabLayout
, so I tried this:
Code sample 3:
<resources>
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<item name="android:tabWidgetStyle">@style/TabsStyle</item>
</style>
<style name="TabsStyle" parent="Widget.Design.TabLayout">
<item name="tabTextColor">@color/tabTextColor</item>
<item name="tabSelectedTextColor">@color/tabSelectedTextColor</item>
</style>
</resources>
But it's not working, the only way I got it working is manually setting them in XML:
<android.support.design.widget.TabLayout
[...]
android:background="?android:attr/colorPrimary"
app:tabTextColor="@color/tabTextColor"
app:tabSelectedTextColor="@color/tabSelectedTextColor" />
Last, I will upvote any reference to good style & theme guides/books. I really need to improve at this.
Thanks in advance.
Globally specify a color for the back arrow in the Toolbar
This is not as straightforward as it probably should be, but try the following:
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<!-- style the back arrow -->
<item name="toolbarNavigationButtonStyle">@style/NavButtonStyle</item>
</style>
<style name="NavButtonStyle" parent="@style/Widget.AppCompat.Toolbar.Button.Navigation">
<item name="android:tint">#FF0000</item>
</style>
It is android:tint
that will change the color of the back arrow.
In general, the default toolbar style is set by the attribute toolbarStyle
. In the XML below, it is set to @style/MyToolbarStyle
.
MyToolbarStyle
defines three attributes that will be used for all toolbars within the app. Here is what one looks like:
<resources>
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
<item name="toolbarStyle">@style/MyToolbarStyle</item>
<item name="titleTextColor">@android:color/holo_red_light</item>
</style>
<style name="MyToolbarStyle" parent="@style/Widget.AppCompat.Toolbar">
<item name="titleTextColor">@android:color/white</item>
<item name="subtitleTextColor">@android:color/holo_green_light</item>
<item name="android:background">@color/vermillion</item>
</style>
</resources>
As you can see, MyToolbarStyle
sets the value of the three attributes. Unfortunately, this approach does not work for all attributes such as colorControlNormal
which, if specified in the theme, will change the color of the back arrow.
Regarding the question about TabLayout
:
There is no pretty solution to globally define attributes for TabLayout
. You can do something like this and just overlay Widget.Design.TabLayout
but you will have to recreate all the attributes defined there and these attributes may change depending upon the version that is running. This works, but may be a problem to maintain. I don't think that it is a good solution.
Another solution is to create your own custom TabLayout
. It will be very simple and will just define tabTextAppearance
as a global default attribute for TabLayout
. The entire custom layout will look like this:
public class MyTabLayout extends TabLayout {
public MyTabLayout(Context context, AttributeSet attrs) {
super(context, attrs, R.attr.tabTextAppearance);
}
}
Once you replace all references to TabLayout
to MyTabLayout
, you will be able to do the following in styles.xml
:
<style name="AppTheme" parent="BaseAppTheme">
<item name="tabTextAppearance">@style/MyTabStyle</item>
</style>
<style name="MyTabStyle" parent="Widget.Design.TabLayout">
<item name="tabTextColor">#FF0000</item>
<item name="tabSelectedTextColor">#00FF00</item>
</style>
This will make the tab text colors red and green but they can be colors that you choose. You can now declare a TabLayout
in XML and have the default style apply to it without having to explicitly specify a style/theme.
The underlying issue is that the CTORs for TabLayout
do not use defStyleResource
which defines the default style to apply to the view that is defined in the theme and tabWidgetStyle
is not it.. (See this.) The custom layout MyTabLayout
circumvents the problem. However, this does raise the question about whether there is a reason the defStyleResource
is not used and maybe we are diving into a briar patch that we may best avoid.
These methods do work, but I have not fully tested them. You will have to make the determination about whether it is better to do what is described here or to simply define the style on a view-by-view basis.
If someone has a standard, Android-approved way to specify TabLayout
attributes globally, I will be glad to hear about it.