I'd like to have two themes in my app: one with normal font size and one with smaller font size. I need to dynamically change themes in the activity's onCreate
or onStart
.
I've defined two themes (file themes.xml
):
<style name="AppBaseTheme" parent="android:Theme.Light">
</style>
<!-- Default theme with normal font size. This one is set for the whole app in the manifest -->
<style name="NormalTheme" parent="AppBaseTheme">
<item name="android:textAppearance">@style/NormalTextSize</item>
<item name="android:textAppearanceLarge">@style/NormalTextSize.Large</item>
<item name="android:textAppearanceMedium">@style/NormalTextSize.Medium</item>
<item name="android:textAppearanceSmall">@style/NormalTextSize.Small</item>
<item name="android:editTextStyle">@style/EditText_NormalTextSize</item>
</style>
<!-- Small font size -->
<style name="SmallFontTheme" parent="NormalTheme">
<item name="android:textAppearance">@style/SmallTextSize</item>
<item name="android:textAppearanceLarge">@style/SmallTextSize.Large</item>
<item name="android:textAppearanceMedium">@style/SmallTextSize.Medium</item>
<item name="android:textAppearanceSmall">@style/SmallTextSize.Small</item>
<item name="android:editTextStyle">@style/EditText_SmallTextSize</item>
</style>
And in the file styles.xml
I've defined style sets for each theme:
<!-- Normal font -->
<style name="NormalTextSize" parent="@android:style/TextAppearance">
<item name="android:textSize">16sp</item>
</style>
<style name="NormalTextSize.Large" >
<item name="android:textSize">22sp</item>
</style>
<style name="NormalTextSize.Medium" >
<item name="android:textSize">18sp</item>
</style>
<style name="NormalTextSize.Small" >
<item name="android:textSize">14sp</item>
</style>
<style name="EditText_NormalTextSize" parent="@android:style/Widget.EditText">
<item name="android:textSize">16sp</item>
</style>
<!-- Small font -->
<style name="SmallTextSize" parent="@android:style/TextAppearance">
<item name="android:textSize">14sp</item>
</style>
<style name="SmallTextSize.Large" >
<item name="android:textSize">20sp</item>
</style>
<style name="SmallTextSize.Medium" >
<item name="android:textSize">16sp</item>
</style>
<style name="SmallTextSize.Small" >
<item name="android:textSize">12sp</item>
</style>
<style name="EditText_SmallTextSize" parent="@android:style/Widget.EditText">
<item name="android:textSize">14sp</item>
</style>
To test the theme change I've created an activity and I've added two TextViews (one with textAppearanceLarge
and one with textAppearanceSmall
). I've also added an EditText and a list view. I haven't touched any style attribute on these views, I've kept them as they are when dropped in the layout editor. My goal is to change the theme for the whole app without having to define style or appearance for each widget.
I've also added some buttons to trigger the theme change: the new theme resource id is stored in preferences, then the activity is self-finished and a new Intent to the same test activity is launched. The activity reads the current theme setting in onCreate
or onStart
and calls setTheme
. This theme setting change works, but only the ListView is resizing the text: the TextViews
and the EditText
don't resize.
So my question is what on earth have I done wrong. I've followed 3-4 tutorials and my styles are consistent with what it is supposed to work.
Notice I've only overrided text appearances in the themes because I thought that almost every text-based widget would resize based on the appearance alone (when dropped from the layout editor, every widget has an appearance). I've readed somewhere that it doesn't work that way (if so, good job guys at Google) and that you need to define text size for every kind of widget inside the themes. Well in the example above I've overrided editTextStyle
and didn't work. I have also tried buttons and text views with identical result. But what puzzles me is that the ListView, which is the most complex widget on screen, is resizing correctly without defining an style for it, while the most simple widgets are not, even when defining styles for those particular kind of widgets!