如何为冰激凌三明治标签之间的分隔符设置样式?

45

我正在使用以下样式以及一组九宫格图像来创建一条红线,代替标准的蓝色线,放在某些冰淇淋三明治标签的底部:

<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>

红线已显示,一切看起来都很好,除了选项卡之间的分隔符。如图绿色框内所示,该线未在分隔符下方绘制。我该如何为此分隔符选择一个可绘制或样式?
android:divider和android:showDividers不负责选项卡之间的分隔符。它们只选择在选项卡图标和选项卡标题之间绘制的分隔符。我隐藏了这些分隔符,因为没有标题,分隔符会看起来奇怪。

Screenshot from the resulting tab bar


更新考虑到Aneal的答案,我添加了一个第二个样式的customTabBar。该样式选择一个可绘制的标记作为分隔符。该分隔符是一个由以下9patch drawable创建的实心黑线:

9patch drawable creating the divider

使用这个可绘制对象来绘制分割线,但旁边也会出现一个空白行:

tab bar with dividers


嗯,可以这样想。如果你对所有内容使用默认的可绘制对象,则分隔线会正确对齐,因此,你更改的某些内容可能是罪魁祸首。如果不是九宫格图像,则可能是选项卡的问题。我不知道,我无法测试你正在使用的可绘制对象,这里也没有其他人可以测试。如果我是你,我会开始逐一检查列表中的项目,看看它们为什么略微偏离中心。检查你的样式和可绘制对象。 - adneal
检查这个链接,它可以帮助自定义选项卡和分隔符:https://dev59.com/em025IYBdhLWcg3wyZEn - Charan Pai
嗨@Janusz,我在蓝色下划线方面遇到了问题,我阅读了所有的教程,但没有什么帮助,你能解释一下如何更改颜色吗?你在选择器xml上做了些什么吗?因为即使我使用你的代码,由于TabBar中的背景,所有的背景都是相同的。如果您能帮助我,我将不胜感激。 - Shayan Pourvatan
你需要创建不同颜色的图片。我建议使用http://jgilfelt.github.io/android-actionbarstylegenerator/,该网站将为您生成所有所需的资源。 - Janusz
谢谢您的回复,我之前看过那个,但是我还是没想通,不管怎样还是谢谢,我会再试试。 - Shayan Pourvatan
显示剩余2条评论
6个回答

51

我移除了所有的样式之后,得到了以下的图片:

在这里输入图片描述

这张图片也包含了小间隙。因此看起来这是一种默认行为。

然而我找到了一个解决方法。我将红线设置为整个选项卡栏的标准背景。这样间隙就会出现,但由于已经显示了包含线条的背景,所以没有人能够看到它。

现在我对我所有的活动都使用以下样式:

<style name="LightThemeSelector" parent="android:Theme.Holo.Light">
    <item name="android:actionBarTabBarStyle">@style/customTabBar</item>
    <item name="android:actionBarTabStyle">@style/customTabStyle</item>
</style>

这个样式用于为选项卡栏内的每个单独的选项卡设置样式:

<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>

为了样式化整个Tabbar,我使用以下样式:

<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>

这种样式定义了我的自定义分隔符,并为选项卡栏定义了背景。作为背景,我直接设置了九宫格可拉伸图片,如果选项卡没有被选择,则绘制该图片。
所有这些的结果是一个带有红色下划线且没有任何间隙的选项卡栏。

enter image description here


我应该怎么做才能使这种风格在2.x操作系统中兼容? - Paresh Mayani
2
你应该使用ActionBarSherlock。 - Richard
但是对于 Widget.Holo.ActionBar.TabView,没有 measureWithLargestChild、android:gravity 和 android:showDividers 这些属性。 - Vishnu Prabhu

22

这是你需要的。

<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>

什么?只需将“@null”更改为您想要的任何内容。我隐藏它们是为了确保在测试时它能正常工作。这正是您所需要的。如果您接受,请检查答案。 - adneal
似乎尝试覆盖TabBar样式的任何属性都不起作用,至少对于ActionBarSherlock而言是如此。 - Etienne Lawlor

8
<style name="AppTheme" parent="AppBaseTheme">
    <item>......
    </item>
    <item name="android:actionBarDivider">@null</item>

</style>

在这里,@null代表不提供任何分隔符。 如果您想自定义分隔符,请使用@drawable / your_divider_image。

6
如果您想去掉分隔符,只需执行以下操作:
<style name="customTabBar" parent="@android:style/Widget.Holo.ActionBar.TabBar">
    <item name="android:divider">@null</item>
</style>

我尝试过这个,但对我没有用。在我的情况下,父级是parent="@style/Widget.Sherlock.ActionBar.TabBar",这是一个ActionBarSherlock样式。 - Etienne Lawlor

6

顺便说一下,这是由于ICS中android:divider属性的LinerLayout类实现中存在的巨大bug引起的。它在Honeycomb中被引入,在ICS中被破坏,在Jelly Bean中再次工作。

问题在于当您使用android:divider时,它会在子元素之间产生小间隔以放置分隔符,但是分隔符不会放置在此空间内,而是放置在其后面,因此它将被选项卡本身覆盖,而空间将保持为空。非常愚蠢的错误。尝试比较4.0和4.1版本的LinerLayout源代码。

是的,解决方案是将分隔符放置在所有选项卡的背景中,它只会在此bug导致的选项卡之间的间隙中可见。


1

根据ATom's answer,以下是一种在所有Android版本中实现类似分隔符的方法。

为了使其正常工作,您不使用任何本地分隔符方法(因为它们在某些版本中无法正常工作)。不要忘记删除设置分隔符的任何代码。

诀窍就是在用于每个选项卡的视图中设置非常小的右边距。这样,将会有一个小间隙,您可以看到背景(TabHost)。为了完成此操作,您将TabHost的背景设置为模拟拉伸的分隔符。

尽管此技巧并不适用于您可能想要的所有可能设计,但对于许多情况(如我所遇到的情况)效果很好。

以下是示例实现:

@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;
}

这是一个样例tab_divider可绘制对象:
<?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>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接