如何设计冰淇淋三明治标签之间的分隔线?

Posted

技术标签:

【中文标题】如何设计冰淇淋三明治标签之间的分隔线?【英文标题】:How to style the divider between Ice Cream Sandwich tabs? 【发布时间】:2012-02-28 15:49:38 【问题描述】:

我使用以下样式和一组九个补丁图像在一些冰淇淋三明治标签的底部创建一条红线,而不是标准的蓝线:

<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:dividerandroid:showDividers 项目不负责选项卡之间的分隔符。他们只选择在选项卡图标和选项卡标题之间绘制的分隔线。我隐藏了那些分隔线,因为没有标题,而且分隔线看起来很奇怪。


更新 考虑到 Aneal 的回答,我添加了第二种样式 customTabBar。该样式选择一个可绘制对象作为分隔线。分隔线是使用以下 9patch drawable 创建的黑色实线:

有了这个drawable,分隔线就被绘制出来了,但它旁边还有一个空行:

【问题讨论】:

问题在于你的九个补丁。如果您在 SDK 中搜索“list_divider_holo_”,您将找到用于 ActionBar 选项卡分隔符的所有九个补丁。如果你想做一个准确的,我会使用 SDK 中的一个作为模板。您也可以尝试调整填充。 我的九个补丁drawable没有问题。按照您的建议使用 SDK 中的可绘制对象可以得到相同的结果。 嗯。像这样想。如果您对所有内容使用默认可绘制对象,则分隔线正确排列,因此,您更改的内容是这里的罪魁祸首。如果不是九个补丁,那么也许是你的标签。我不知道,我无法测试您正在使用的可绘制对象,这里的其他人也无法测试。如果我是你,我会开始检查列表中的内容,看看为什么它们会稍微偏离中心。检查您的样式和可绘制对象。 检查这个..这将有助于自定义标签和分隔线..***.com/questions/5799320/… 嗨@Janusz,我有蓝色下划线的问题,我阅读了所有教程但没有任何帮助,你能解释一下你是如何改变颜色的吗?你在选择器 xml 上做了什么吗?因为即使我使用你的代码,所有背景都是相同的,因为 TabBar 中的背景,如果帮助我,我将不胜感激 【参考方案1】:

删除我使用的所有样式后,我得到了以下图像:

此图像还包含小间隙。因此,这似乎是某种默认行为。

但是我找到了解决问题的方法。我将红线设置为整个标签栏的标准背景。这样间隙就会出现,但没有人能看到它,因为显示了已经包含线条的背景。

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

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

这种风格定义了我的自定义分隔线,也定义了标签栏的背景。作为背景,我直接设置了如果未选择选项卡则绘制的九个补丁可绘制对象。 所有这些的结果是一个带有红色下划线的标签栏,没有任何间隙。

【讨论】:

我应该怎么做才能使这种风格在 2.x 操作系统中兼容? 你应该使用 ActionBarSherlock 但是对于 Widget.Holo.ActionBar.TabView ,没有像 measureWithLargestChild, android:gravity, android:showDividers 这样的属性。【参考方案2】:

给你。

<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”更改为您想要的任何内容。我把它们藏起来以确保它在我测试时能正常工作。这正是你所需要的。如果您接受,请检查答案。 似乎试图覆盖 TabBar 样式的任何属性都不起作用。至少对于 ActionBarSherlock。【参考方案3】:
<style name="AppTheme" parent="AppBaseTheme">
    <item>......
    </item>
    <item name="android:actionBarDivider">@null</item>

</style>

这里@null 是为了不提供任何分隔符 如果你想自定义你的分隔线而不是使用@drawable/your_divider_image

【讨论】:

【参考方案4】:

如果您想摆脱分隔线,您可以这样做:

<style name="customTabBar" parent="@android:style/Widget.Holo.ActionBar.TabBar">
    <item name="android:divider">@null</item>
</style>

【讨论】:

我试过这个并没有为我工作。在我的例子中,父级是 parent="@style/Widget.Sherlock.ActionBar.TabBar",这是一种 ActionBarSherlock 风格。【参考方案5】:

顺便说一句。这是由 android:divider 属性的 LinerLayout 类实现中的 ICS 中的巨大错误引起的。它是在 Honeycomb 中引入的,在 ICS 中被破坏并在 Jelly Bean 中再次起作用。

问题是,当您使用 android:divider 时,它会在它的子元素之间留出很小的空间来放置分隔符,但是将分隔符 no 放置在这个空间中,但是在它之后,所以它会被选项卡本身重叠并且空间将保持为空。非常愚蠢的错误。尝试比较 4.0 和 4.1 版本的 LinerLayout 源代码。

是的,解决方案是将分隔符放在所有选项卡的背景中,并且仅在此错误引起的选项卡之间的间隙中可见。

【讨论】:

【参考方案6】:

基于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_dividerdrawable:

<?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: 
                android:color="@color/tab_background_color"/>
</shape>

【讨论】:

以上是关于如何设计冰淇淋三明治标签之间的分隔线?的主要内容,如果未能解决你的问题,请参考以下文章

冰淇淋三明治中 HttpURLConnection 的 FileNotFoundException

从冰淇淋三明治添加应用程序功能

更改冰淇淋三明治中的状态栏颜色 [重复]

如何读取 Stock CPU Usage 数据

Dalvik 的内存模型和 Java 的一样吗?

安卓系统等级比较