I'm using the following style together with a set of nine patch images to create a red line at the bottom of some Ice Cream Sandwich tabs instead of the standard blue line:
<style name="customTabStyle" parent="#android:style/Widget.Holo.ActionBar.TabBar">
<item name="android:tabStripLeft">#null</item>
<item name="android:tabStripRight">#null</item>
<item name="android:tabStripEnabled">false</item>
<item name="android:showDividers">none</item>
<item name="android:measureWithLargestChild">true</item>
<item name="android:background">#drawable/tab_line</item>
<item name="android:gravity">center</item>
</style>
<style name="customTabBar" parent="#android:style/Widget.Holo">
<item name="android:showDividers">middle</item>
<item name="android:divider">#drawable/divider2</item>
<item name="android:dividerPadding">0dp</item>
</style>
<style name="LightThemeSelector" parent="android:Theme.Holo.Light">
<item name="android:actionBarTabStyle">#style/customTabStyle</item>
<item name="android:actionBarTabBarStyle">#style/customTabBar</item>
</style>
The red line is shown and everyting looks good, except for the divider between the tabs.
As you can see inside the green box in the image the line is not drawn below the divider.
How do I select a drawable, or a style for this divider?
The android:divider and android:showDividers items are not responsible for the divider between tabs. They only select the divider drawn between the tab icon and the tab title. I hide those dividers because there isn't a title and a divider would look strange.
Update With the answer from Aneal in mind I added a second style customTabBar. The style selects a drawable as a divider. The divider is a solid black line created with the following 9patch drawable:
With this drawable the divider is drawn, but there is also a blank line next to it:
After removing every style I use I got the following image:
This image also contains the small gaps. Therefore it seems that this is some kind of default behavior.
However I found a way to work around the problem. I set the redline as a standard Background for the whole tabbar. This way the gap appears but nobody can see it because the background, that already contains the line is shown.
I now use the following style for all my activities:
<style name="LightThemeSelector" parent="android:Theme.Holo.Light">
<item name="android:actionBarTabBarStyle">#style/customTabBar</item>
<item name="android:actionBarTabStyle">#style/customTabStyle</item>
</style>
This style is used to style each single tab inside the tabbar:
<style name="customTabStyle" parent="#android:style/Widget.Holo.ActionBar.TabView">
<item name="android:showDividers">none</item>
<item name="android:measureWithLargestChild">true</item>
<item name="android:background">#drawable/tab_line</item>
<item name="android:gravity">center</item>
</style>
To style the whole Tabbar i use the following style:
<style name="customTabBar" parent="#android:style/Widget.Holo.ActionBar.TabBar">
<item name="android:showDividers">middle</item>
<item name="android:divider">#drawable/divider</item>
<item name="android:dividerPadding">0dp</item>
<item name="android:background">#drawable/tab_unselected</item>
</style>
This style defines my custom divider and also defines the background for the tabbar. As background I directly set the nine patch drawable that is drawn if a tab is not selected.
The result of all this is a tabbar with a red underline without any gaps.
Here you go.
<style name="YourTheme" parent="#android:style/Theme.Holo.Light">
<item name="android:actionBarTabBarStyle">#style/Divider</item>
</style>
<style name="Divider" parent="#android:style/Widget.Holo.ActionBar.TabBar">
<item name="android:divider">#drawable/your_divider_drawable_here</item>
<item name="android:showDividers">middle</item>
<item name="android:dividerPadding">12dip</item>
</style>
<style name="AppTheme" parent="AppBaseTheme">
<item>......
</item>
<item name="android:actionBarDivider">#null</item>
</style>
here #null is for not to provide any divider
and if you want to customize your divider than use #drawable/your_divider_image
If you'd like to get rid of dividers you could do just this:
<style name="customTabBar" parent="#android:style/Widget.Holo.ActionBar.TabBar">
<item name="android:divider">#null</item>
</style>
Btw. This is caused by huge bug in the ICS in LinerLayout class implementation of android:divider attribute. It was introduced in Honeycomb, broken in ICS and working again in Jelly Bean.
Problem is that when you use android:divider it make small space between it child for place divider, but place divider no into this space, but after it, so it will be overlap by the tab itself and space will stay empty. Very stupid bug. Try to compare LinerLayout source code for release 4.0 and 4.1.
And yes solution is put the delimiter to the background of all tabs and it will be visible only in the gaps between tabs caused by this bug.
Based on ATom's answer, here's a way to have something resembling dividers in all android versions.
In order to make this work, you don't use any of the native divider methods (because they are broken in some versions). Don't forget removing any code where you set dividers.
The trick is simply setting a very small right margin in the views used for each tab. This way, there will be a small gap where you can see the background (the TabHost). To finish this, you set the background on the TabHost to mimic stretched divider.
Although this trick doesn't work for all possible designs you might want, it works well for many cases like the one I had.
Here's a sample implementation:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// ...
// inflate or create tabHost in code
// call tabHost.setup
// ...
TabWidget tabWidget = tabHost.getTabWidget();
tabWidget.setBackgroundResource(R.drawable.tab_divider);
// ... add tabs
for( int i = 0; tabWidget.getChildCount()-1; i++) {
View view = tabWidget.getChildAt(i);
LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) view.getLayoutParams();
layoutParams.rightMargin = getResources().getDimensionPixelSize(R.dimen.tab_divider_width); //1dp
view.setLayoutParams(layoutParams);
}
return tabHost;
}
Here's a sample tab_divider drawable:
<?xml version="1.0" encoding="utf-8"?>
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="#color/divider_color" />
<stroke android:width="#dimen/tab_divider_vertical_padding"
android:color="#color/tab_background_color"/>
</shape>
Related
I've been overriding the default button style in my app like this:
<style name="ButtonStyle" parent="Base.Widget.AppCompat.Button">
<item name="android:textAllCaps">false</item>
<item name="android:textSize">18sp</item>
<item name="android:textColor">#color/primaryTextContrast</item>
<item name="android:background">#drawable/button</item>
</style>
That worked fine until Nougat, but with Nougat there's been a change (a bug fix I think) such that this style also applies to buttons in dialogs, while in previous versions it did not. This has the effect of giving the dialog buttons white text on a white background.
In case it's relevant, button is a 9 patch in drawable and is overridden in drawable-v21:
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="?attr/colorControlHighlight">
<item android:drawable="?attr/colorPrimary"/>
</ripple>
The primary color is dark, and primaryTextContrast is white. Dialogs do not get dark buttons in Nougat for some reason - they seem to pick up the text color but not the background. So I need to either let the dialog buttons do their default thing, or make the buttons fully inherit the style with a dark background and white text.
#nasch, Dialog buttons use button bar style. In this scenario, you could do something like
<style name="buttonBarButtonStyle" parent="Widget.AppCompat.Button.ButtonBar.AlertDialog">
<item name="android:textColor">#color/colorPrimary</item>
</style>
In your main style definition, you then define
<style name="MyCustomTheme" parent="Theme.AppCompat">
<item name="buttonBarButtonStyle">#style/buttonBarButtonStyle</item>
...
Hope this helps.
I have my style defined as follows:
<style name="actionBarTheme" parent="android:style/Widget.Holo.Light.ActionBar">
<item name="android:background">#drawable/button_style</item>
<item name="android:titleTextStyle">#style/actionBarTitleText</item>
</style>
And the actionBar is actually of the color defined in button_style (correctly working in other parts of the code). The problem is that the items are not working correctly (the background color is too light).
Any idea on how to solve this? Thanks
EDIT:
In the picture there is the touch-feedback that I have now. The button_style has another touch effect (a darker one) since this is almost invisible.
You can have this affect with actionButtonStyle
<style name="appTheme">
<item name="android:actionBarStyle">#style/actionBarTheme</item>
<item name="android:actionButtonStyle">#style/actionButtonTheme</item>
</style>
and then place your button style as the background of that.
<style name="actionButtonTheme">
<item name="android:background">#drawable/button_style</item>
</style>
You will still need to set the background of your action bar but this only needs to be a colour or drawable image as that is all that will actually be used.
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.
I'm struggling with styling the ActionBar. My app has an ActionBar with three tabs. I'm trying to get the selected tab to have a background color, and the unselected tabs to show a different color. I'm following this reference: Customizing Action Bar. But all the TABs are showing the Selected color.
My styles.xml file is as follows:
<style name="MyActionBarTabStyle" parent="android:style/Widget.Holo.Light.ActionBar.TabBar">
<item name="android:background">#drawable/tab_background</item>
<item name="android:paddingLeft">32dp</item>
<item name="android:paddingRight">32dp</item>
</style>
<style name="MyActionBarTabBarStyle" parent="android:style/Widget.Holo.Light.ActionBar.TabBar">
<item name="android:background">#drawable/red</item>
</style>
<style name="AppTheme.Light" parent="#android:style/Theme.Holo.Light">
<item name="android:actionBarStyle">#style/ActionBar.Light</item>
<item name="android:actionBarTabStyle">#style/MyActionBarTabStyle</item>
<item name="android:actionBarTabBarStyle">#style/MyActionBarTabBarStyle</item>
</style>
tab_background is just a 9 patch. I'm also not sure if I'm inheriting the action bar tab from the correct parent (parent="android:style/Widget.Holo.Light.ActionBar.TabBar). I've looked through the references & find it very difficult to understand the style hierarchy
Why wont my tabs show selected or no? Thanks in advance for your assistance.
I solved my problem. I didn't use State List Drawables initially. I used the background image directly instead of going via the StateListDrawable. Using StateListDrawable, you can set a different background based on whether the tag is selected or not.
So I added the file tab_background_select.xml
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_selected="true"
android:drawable="#drawable/tab_background" />
</selector>
and I referenced this from my styles.xml:
<item name="android:background">#drawable/tab_background_select</item>
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>