以编程方式更改ActionBar选项卡下划线颜色

22

我已经通过以下方式创建了操作栏:

ActionBar actionbar = getActionBar()

通过更改操作栏的背景色

actionbar.setBackgroundDrawable(actionBarBackgroundImage);

现在我需要以编程方式更改操作栏选项卡的下划线颜色。是否有任何方法可以更改操作栏选项卡的下划线颜色?


这些答案都没有对您有用吗? - QED
4
这里指定的代码仅适用于使用xml布局。我需要通过Java代码更改ActionBar颜色。有没有任何选项可以更改操作栏默认的蓝色下划线颜色? - Karthick
1
@Karthick,你解决了这个问题吗?想到这不可能实现真是令人失望。 - Rymnel
@Karthick,你有解决方案吗?如果有,请告诉我。我也在寻找通过JAVA代码来改变ActionBar背景颜色的方法,我已经尝试使用setBackgroundDrawable(..)了。 - Sun
你找到答案了吗?@Karthick 我也遇到了同样的问题,请告诉我你的解决方案。 - user5085848
7个回答

10

9
这里有一种更简单的方法。我知道你在寻找编程更改,但这个方法真的非常简单。
我已经为此苦苦挣扎了几天,但终于找到了解决方案。我正在使用AppCompat。您可以在主题中设置colorAccent,这将更改操作栏上的突出显示颜色。像这样:
<item name="colorAccent">@color/highlightcolor</item>

以下是上下文:

<style name="LightTheme" parent="Theme.AppCompat.Light.DarkActionBar">
    <item name="colorPrimary">@color/darkgrey</item>
    <item name="colorPrimaryDark">@color/black</item>
    <item name="colorAccent">@color/highlightcolor</item>
</style>

我最初发布这个答案的地方:Android选项卡下划线颜色不变


如果您的最低API版本小于API 21,会怎么样? - ban-geoengineering
这就是AppCompat为您所做的。您的项目具有低于21的最小API,而AppCompat为在低于21的操作系统上运行的应用程序提供api-21级别的行为。 - Kenny Wyland

6
我建议您使用ActionBarSherlock。库中有一个名为“Style ActionBar”的示例可用。(这是更改ActionBar选项卡下划线颜色的唯一方法)。
如果您已经自定义了ActionBar,则必须将此样式添加到ActionBar样式中。
或者,以下是如何执行此操作的方法。

enter image description here

创建如下样式(这里我使用了ActionBarShareLock,如果您不想使用,则可以使用android-support-v4.jar来支持所有Android操作系统版本)

<style name="Theme.AndroidDevelopers" parent="Theme.Sherlock.Light">
        <item name="android:actionBarTabStyle">@style/MyActionBarTabStyle</item>
        <item name="actionBarTabStyle">@style/MyActionBarTabStyle</item>
    </style>

    <!-- style for the tabs -->
    <style name="MyActionBarTabStyle" parent="Widget.Sherlock.Light.ActionBar.TabBar">
        <item name="android:background">@drawable/actionbar_tab_bg</item>
        <item name="android:paddingLeft">32dp</item>
        <item name="android:paddingRight">32dp</item>

actionbar_tab_bg.xml

<item android:state_focused="false" android:state_selected="false" android:state_pressed="false" android:drawable="@drawable/ad_tab_unselected_holo" />
<item android:state_focused="false" android:state_selected="true"  android:state_pressed="false" android:drawable="@drawable/ad_tab_selected_holo" />
<item android:state_selected="false" android:state_pressed="true" android:drawable="@drawable/ad_tab_selected_pressed_holo" />
<item android:state_selected="true"  android:state_pressed="true" android:drawable="@drawable/ad_tab_selected_pressed_holo" />

在Android清单文件中的活动中应用此样式。
<activity
            android:name="com.example.tabstyle.MainActivity"
            android:label="@string/app_name"
            android:theme="@style/Theme.AndroidDevelopers" >

如需更详细信息,请查看答案文章


编辑日期:2015年9月29日

ActionBarSherlock已经过时,您可以使用Android的design支持库和Android应用程序appcompat库来替代TOOLBAR(Action-Bar已过时)和TABS。

像下面这样使用TabLayout

<android.support.design.widget.TabLayout
            android:id="@+id/tabs"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:tabGravity="center"
            app:tabMode="scrollable"
            app:tabSelectedTextColor="@color/white"
            app:tabIndicatorColor="@color/colorPrimary"
            app:tabIndicatorHeight="2dip"
            app:tabTextAppearance="?android:attr/textAppearanceMedium"
            app:tabTextColor="@color/colorAccent" />

这里是 Android 设计支持库带有选项卡的示例



4

请参考此文档,学习如何自定义操作栏。

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <!-- the theme applied to the application or activity -->
    <style name="CustomActivityTheme" parent="@android:style/Theme.Holo">
        <item name="android:actionBarStyle">@style/MyActionBar</item>
        <!-- other activity and action bar styles here -->
    </style>

    <!-- style for the action bar backgrounds -->
    <style name="MyActionBar" parent="@android:style/Widget.Holo.ActionBar">
        <item name="android:background">@drawable/ab_background</item>
        <item name="android:backgroundStacked">@drawable/ab_background</item>
        <item name="android:backgroundSplit">@drawable/ab_split_background</item>
    </style>
</resources>

4
谢谢回复Sino。我知道自定义操作栏的方式。但是我需要通过编写代码来自定义操作栏选项卡。 - Karthick
@Karthick - 你修好了吗? - Anjum

2
我尝试了这里和其他地方发布的许多建议,但都没有成功。不过我想我成功地拼凑出了一个(虽然不完美)的解决方案。
TabWidget使用选择器。它基本上根据选项卡的状态(已选、按下等)显示不同的9-patch图片。最终我发现你可以通过编程方式生成一个选择器。我从http://android-holo-colors.com/(颜色:#727272,TabWidget:是)生成了9-patch图像。
最大的问题是设置颜色。设置颜色滤镜没有作用。所以,我最终在循环内改变了9-patch图片中每个像素的颜色。
...    
/**
 * <code>NinePatchDrawableUtility</code> utility class for manipulating nine patch resources.
 * 
 * @author amossman
 *
 */
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
public class NinePatchDrawableUtility {

    // Matches the colors in the supported drawables
    private static final int TAB_UNDERLINE_HIGHLIGHT_COLOR = 1417247097;
    private static final int TAB_UNDERLINE_COLOR = -8882056;
    private static final int TAB_PRESSED_COLOR = -2122745479;

    private Resources resources;

    public NinePatchDrawableUtility(Resources resources) {
        this.resources = resources;
    }

    /**
     * Create a <code>StateListDrawable</code> that can be used as a background for the {@link android.widget.TabWidget}</br></br>
     * 
     * <code>
     * FragmentTabHost tabHost = ...</br>
     * NinePatchUtility ninePatchUtility = new NinePatchUtility(getResources());</br>
     * TabWidget tabWidget =  tabHost.getTabWidget();</br>
     * for (int i = 0; i < tabWidget.getChildCount(); i++) {</br>
     * &nbsp;&nbsp;&nbsp;tabWidget.getChildAt(i).setBackground(ninePatchUtility.getTabStateListDrawable(titleColor));</br>
     * }
     * </code>
     * 
     * @param tintColor The color to tint the <code>StateListDrawable</code>
     * @return A new <code>StateListDrawable</code> that has been tinted to the given color
     */
    public StateListDrawable getTabStateListDrawable(int tintColor) {
        StateListDrawable states = new StateListDrawable();
        states.addState(new int[] {android.R.attr.state_pressed},
            changeTabNinePatchColor(resources, R.drawable.cc_tab_selected_pressed_holo, tintColor));
        states.addState(new int[] {android.R.attr.state_focused},
            changeTabNinePatchColor(resources, R.drawable.cc_tab_selected_focused_holo, tintColor));
        states.addState(new int[] {android.R.attr.state_selected},
            changeTabNinePatchColor(resources, R.drawable.cc_tab_selected_holo, tintColor));
        states.addState(new int[] { },
            changeTabNinePatchColor(resources, R.drawable.cc_tab_unselected_holo, tintColor));
        return states;
    }

    /**
     * Change the color of the tab indicator.</br></br>
     * 
     * Supports only the following drawables:</br></br>
     * 
     * R.drawable.cc_tab_selected_pressed_holo</br>
     * R.drawable.cc_tab_selected_focused_holo</br>
     * R.drawable.cc_tab_selected_holo</br>
     * R.drawable.cc_tab_unselected_holo</br></br>
     * 
     * Note: This method is not efficient for large <code>Drawable</code> sizes.
     * 
     * @param resources Contains display metrics and image data
     * @param drawable The nine patch <code>Drawable</code> for the tab
     * @param tintColor The color to tint the <code>Drawable</code>
     * @return A new <code>NinePatchDrawable</code> tinted to the given color
     */
    public NinePatchDrawable changeTabNinePatchColor(Resources resources, int drawable, int tintColor) {

        int a = Color.alpha(tintColor);
        int r = Color.red(tintColor);
        int g = Color.green(tintColor);
        int b = Color.blue(tintColor);
        BitmapFactory.Options opt = new BitmapFactory.Options();
        opt.inMutable = true;
        Bitmap bitmap = BitmapFactory.decodeResource(resources, drawable, opt);
        for (int x = 0; x < bitmap.getWidth(); x++) {
            for (int y = 0; y < bitmap.getHeight(); y++) {
                int color = bitmap.getPixel(x, y);
                if (color == TAB_PRESSED_COLOR) {
                    bitmap.setPixel(x, y, Color.argb((int)(a * 0.5), r, g, b));
                } else if (color == TAB_UNDERLINE_HIGHLIGHT_COLOR) {
                    bitmap.setPixel(x, y, Color.argb((int)(a * 0.9), r, g, b));
                } else if (color == TAB_UNDERLINE_COLOR) {
                    bitmap.setPixel(x, y, tintColor);
                }
            }
        }
        return new NinePatchDrawable(resources, bitmap, bitmap.getNinePatchChunk(), new Rect(), null);
    }

}

使用示例:

/**
 * Theme the tab widget with the defined background color and title color set
 * in the TabManager
 * @param tabWidget
 */
@SuppressWarnings("deprecation")
@SuppressLint("NewApi")
public void theme(TabWidget tabWidget) {
    ColorDrawable backgroundDrawable = new ColorDrawable(backgroundColor);
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
        tabWidget.setBackground(backgroundDrawable);
        tabWidget.setAlpha(0.95f);
    } else {
        backgroundDrawable.setAlpha(242);
        tabWidget.setBackgroundDrawable(backgroundDrawable);
    }
    NinePatchDrawableUtility ninePatchUtility = new NinePatchDrawableUtility(resources);
    for (int i = 0; i < tabWidget.getChildCount(); i++) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
            tabWidget.getChildAt(i).setBackground(ninePatchUtility.getTabStateListDrawable(titleColor));
        } else {
            tabWidget.getChildAt(i).setBackgroundDrawable(ninePatchUtility.getTabStateListDrawable(titleColor));
        }
        View tabView = tabWidget.getChildTabViewAt(i);
        tabView.setPadding(0, 0, 0, 0);
        TextView tv = (TextView) tabView.findViewById(android.R.id.title);
        tv.setSingleLine(); // set the texts on the tabs to be single line
        tv.setTextColor(titleColor);
    }
}

你能展示一下如何使用这个类来设置选中的标签颜色吗?在changeTabNinePathColor()方法中使用了哪个图像资源? - droideckar
请参考上面的帖子中的getTabStateListDrawable函数,了解如何使用changeTabNinePatchColor。如果您想要设置选项卡的整个状态列表,可以使用tabWidget.getChildAt(i).setBackground(ninePatchUtility.getTabStateListDrawable(color))或setBackgroundDrawable(根据SDK版本而定)。 - user3474507

1

经过长达一天的搜索,我找到了更改选项卡高亮颜色的解决方案。只需要两行代码就可以完美实现!

前往values/styles.xml并在ActionBar主题中添加以下代码:

<item name="colorAccent">@color/Tab_Highlighter</item>

现在在colors.xml中为Tab_Highlighter指定颜色即可。

<color name="Tab_Highlighter">#ffffff</color>

请在代码上留下评论,如果有任何问题。它对我来说运行良好。 - Arun
这些问题是3年前提出的,我认为对于原帖作者来说已经不再相关了。 - user2807083
1
我试图更改选项卡的高亮显示器。尝试了这里提供的所有解决方案,但都没有起作用。这个解决方案有效,所以我认为它可能会帮助正在寻找解决方案的某个人。 - Arun

-1
你可以使用以下代码:

actionBar.setStackedBackgroundDrawable(new ColorDrawable(yourColor));


2
它会给选项卡的整个背景着色。你能告诉我如何仅更改下划线条的颜色吗? - v01d

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