How to change ActionBar Tab styles in API 14 and above - android

I am trying to fit 5 tabs at the top using the ViewPager view. I need those 5 tabs to fit on the screen width. It does not, so I was able to decrease the text size to make it fit, but then the text is too small. So now I am trying to take away some of the padding for each tab like so:
<style name="CustomActionBarTheme" parent="Theme.AppCompat.Light">
<item name="android:actionBarTabTextStyle">#style/MyActionBarTextTheme</item>
<!-- <item name="android:actionBarStyle">#style/MyActionBarTheme</item> -->
</style>
<style name="MyActionBarTheme" parent="Widget.AppCompat.Light.Base.ActionBar.TabView">
<item name="android:padding">0dp</item>
</style>
<style name="MyActionBarTextTheme" parent="Widget.AppCompat.Light.ActionBar.TabText">
<item name="android:textSize">10sp</item>
</style>
Except nothing happens. In fact the tabs completely disappear. Is there something more specific I should be doing? Thanks.

Related

Themes for different text sizes not working

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!
The themes were ok.
The problem was the activity. You need to call setTheme before setContentView.
Kudos to #mozarty for his answer

Fix actionbar tab width

The layout below has 4 tabs and I have to scroll through to open the different tabs. Is there a way to fix the tab width so that all 4 tabs can be displayed on screen?
You can use fixed tabs instead of scrollable ones.
See
http://developer.android.com/design/building-blocks/tabs.html
and
http://developer.android.com/training/implementing-navigation/lateral.html
(FragmentPagerAdapter vs. FragmentStatePagerAdapter)
But keep in mind that different users have different screen sizes and at some point the content of your tabs can't get any smaller without becoming unreadable.
The action bar tab has a build in padding of 16 dip for left and right.
<style name="Widget.AppCompat.Base.ActionBar.TabView" parent="">
<item name="android:background">#drawable/abc_tab_indicator_ab_holo</item>
<item name="android:gravity">center_horizontal</item>
<item name="android:paddingLeft">16dip</item>
<item name="android:paddingRight">16dip</item>
<item name="android:minWidth">80dip</item>
</style>
In order to override the padding you need to override those properties:
<style name="ActionBarTabStyle.MY_STYLE" parent="#style/Widget.AppCompat.Light.ActionBar.TabView">
<item name="android:background">#drawable/tab_indicator_ab_MY_STYLE_light</item>
<item name="android:paddingLeft">1dip</item>
<item name="android:paddingRight">1dip</item>
</style>
This fixed the problem to me.

how to remove spacing between ActionBar icons

Once again I'm fighting with ActionBar styles for SDK 14 and above. I'm trying to remove/reduce spacing between Tab icons since the default spacing does not fit well in my design. Currently my style looks like:
<style name="sMain" parent="#android:style/Theme.Holo">
<item name="android:actionBarStyle">#style/mTabAreaBackground</item>
<item name="android:actionBarTabStyle">#style/ActionBarTabStyle</item>
</style>
<style name="mTabAreaBackground" parent="#android:style/Widget.Holo.ActionBar.Solid">
<item name="android:backgroundStacked">#2b2f33</item>
</style>
<style name="ActionBarTabStyle" parent="#android:style/Widget.Holo.ActionBar.TabView">
<item name="android:background">#android:color/transparent</item>
<!-- below attributes have no effect -->
<item name="android:width">0dp</item>
<item name="android:height">0dp</item>
</style>
I "removed" the active Tab indicator by making it transparent since my Tab icons already have one. I assumed that the spacing between Tab icons was somehow related to the Tab indicator, which was still there though I made it transparent. Therefore I tried to apply a width and height of 0 in the same style (inherited from style/Widget.Holo.ActionBar.TabView). I don't know if my assumption was incorrect or I'm doing something wrong, I also could not find any documentation/examples related to adjusting spacing between Tab icons.
Any suggestions are appreciated.
AFAIK, the spacing is because of the padding on the TabView.
You should changing the padding on the TabView something like below.
<style name="ActionBarTabStyle" parent="#android:style/Widget.Holo.ActionBar.TabView">
<item name="android:background">#android:color/transparent</item>
<item name="android:paddingLeft">2dp</item>
<item name="android:paddingRight">2dp</item>
</style>
The default padding on the TabView seems to be 16dp.

Actionbar fills transparent icon pixels with wrong background

I am using actionbar sherlock. I have an icon with transparent pixels. But when I run my app, it seems "something" is replacing these transparent pixels with the main background from the theme, not the actionbar background.
It does not matter if the main background is specified as a #color or a #drawable (9 patch) but in the latter case (which is what I actually want) there is an additional quirk in that a few pixels of the main background 9 patch appear at the right(!) hand edge of the actionbar. Go figure.
I have no idea what's going on here. Just that if I remove the background items from the main style, the actionbar looks as it should (so that seems to be the problem).
Has anyone else seen such behaviour before? Thanks for taking a look!
I'll paste my style.xml below:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="ViewPagerIndicator">
<attr name="vpiSubTabPageIndicatorStyle" format="reference"/>
</declare-styleable>
<style name="Theme.StandBy" parent="Theme.Sherlock.Light.DarkActionBar">
<item name="vpiTabPageIndicatorStyle">#style/CustomTabPageIndicator</item>
<item name="vpiSubTabPageIndicatorStyle">#style/CustomSubTabPageIndicator</item>
<item name="android:actionBarStyle">#style/Theme.StandBy.App.ActionBar</item>
<item name="actionBarStyle">#style/Theme.StandBy.App.ActionBar</item>
<!-- ------------------------------------------ ->
<!-- I tried both of these, but can't get transparent pixels in my icon to work --->
<!-- when I use the 9 patch (frg_background) in stead of a plain color, there -->
<!-- are extra artefacts in that some of the 9 patch pixels end up on the righthand -->
<!-- side of the action bar -->
<!--<item name="android:background">#drawable/frg_background</item>
<item name="background">#drawable/frg_background</item>-->
<item name="android:background">#color/cream</item>
<item name="background">#color/cream</item>
<!-- ------------------------------------------ ->
</style>
<style name="Theme.StandBySubTab" parent="Theme.Sherlock.Light.DarkActionBar">
<item name="vpiTabPageIndicatorStyle">#style/CustomSubTabPageIndicator</item>
</style>
<style name="Theme.StandBy.App.ActionBar" parent="Widget.Sherlock.ActionBar">
<!--
Both `android:xyz` and `xyz` need to be set to support 4.x and 2.x devices.
-->
<item name="android:displayOptions">showHome</item>
<item name="displayOptions">showHome</item>
<item name="android:background">#drawable/bar</item>
<item name="background">#drawable/bar</item>
</style>
<!-- top tab style -->
<style name="CustomTabPageIndicator" parent="Widget.TabPageIndicator">
<item name="android:background">#drawable/tab_background</item>
<item name="android:textAppearance">#style/CustomTabPageIndicator.Text</item>
<item name="android:divider">#drawable/tab_divider</item>
<item name="android:showDividers">middle</item>
<item name="android:paddingLeft">4dp</item>
<item name="android:paddingRight">4dp</item>
</style>
<style name="CustomTabPageIndicator.Text">
<item name="android:textColor">#color/tab_text</item>
<item name="android:textSize">10sp</item>
<item name="android:textStyle">bold</item>
</style>
<!-- sub tab style -->
<style name="CustomSubTabPageIndicator" parent="Widget.TabPageIndicator">
<item name="android:background">#drawable/sub_background</item>
<item name="android:textAppearance">#style/CustomSubTabPageIndicator.Text</item>
<item name="android:paddingLeft">4dp</item>
<item name="android:paddingRight">4dp</item>
</style>
<style name="CustomSubTabPageIndicator.Text">
<item name="android:textColor">#color/sub_text</item>
<item name="android:textSize">10sp</item>
<item name="android:textStyle">bold</item>
</style>
</resources>
EDIT: since the problem goes away if I do not specify background and android:background in my main style (Theme.StandBy) it occurred to me I might be asking the wrong question. My purpose in putting these items in is to specify a default background for all of my fragments (content of tabs). That works, but has the unwanted side-effects I mentioned above. Should I be doing this in another way? Thanks for any suggestions!
Properties that you set on the theme will be inherited by EVERY view when the view resolves its styles. In your case, every view that doesn't have an explicit background set somewhere else will render an #color/cream background. This is bound to cause the kinds of visual problems you're experiencing, as well as creating massive amounts of unnecessary overdraw.
A much better way to apply common styling to your fragments is to simply create a style
<style name="Fragment">
<item name="android:background">#color/cream</item>
</style>
and reference it from the root view of each fragment, e.g.
<LinearLayout style="#style/Fragment">
...
</LinearLayout>
This means a bit of extra typing as the reference to the style needs to go into each fragment, but there is no good way to avoid this -- Conceptually only View classes can have their own default style set by the theme (e.g. you can point the textViewStyle attribute at a style definition, and it will apply to all TextViews). However Fragments (or Activities for that matter) aren't Views, so this mechanism doesn't apply.

Android ActionBar Sherlock - Remove divider between tabs altogether

I'm trying to remove the divider between the tabs in an ActionBar (actually an ActionBarSherlock) altogether; i.e. no image between tabs and no gap between the tabs either (I'm using a tiled image background in the tabs). Ideally, I'd like the dividers removed in the XML, rather than in code.
I've tried a few approaches, but nothing seems to be working, such as:
<style name="Theme.MyTheme.ActionBarTab" parent="Widget.Sherlock.ActionBar.TabBar">
<item name="android:divider">#null</item>
<item name="divider">#null</item>
<item name="actionBarDivider">#drawable/empty</item>
<item name="android:showDividers">none</item>
</style>
Turns out I was setting the wrong style. The android:showDividers attribute does work, but when it's applied to the style that inherits from the Widget.Sherlock.ActionBar.TabBar style. So the relevant bits of XML are:
<style name="Theme.Client" parent="Theme.Sherlock.Light.DarkActionBar">
<item name="android:actionBarTabBarStyle">#style/Theme.Client.ActionBarTabBar</item>
<item name="actionBarTabBarStyle">#style/Theme.Client.ActionBarTabBar</item>
</style>
<style name="Theme.Client.ActionBarTabBar" parent="Widget.Sherlock.ActionBar.TabBar">
<item name="android:background">#drawable/tab_bar_bg_tiled</item>
<item name="background">#drawable/tab_bar_bg_tiled</item>
<item name="android:showDividers">none</item>
</style>

Categories

Resources