209

我在 ICS 应用程序中使用带有 holo.light 主题的标准 Switch 控件。

我想将切换按钮的突出显示或开启状态颜色从标准的浅蓝色更改为绿色。

这应该很容易,但我似乎无法弄清楚如何去做。

4

24 回答 24

315

派对迟到了,但我就是这样做的

风格

 <style name="SCBSwitch" parent="Theme.AppCompat.Light">
        <!-- active thumb & track color (30% transparency) -->
        <item name="colorControlActivated">#46bdbf</item>

        <!-- inactive thumb color -->
        <item name="colorSwitchThumbNormal">#f1f1f1
        </item>

        <!-- inactive track color (30% transparency) -->
        <item name="android:colorForeground">#42221f1f
        </item>
    </style>

颜色

在此处输入图像描述

布局

<android.support.v7.widget.SwitchCompat
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentRight="true"
    android:checked="false"
    android:theme="@style/SCBSwitch" />

结果

查看启用和禁用开关的颜色变化

在此处输入图像描述

于 2016-07-09T05:01:05.360 回答
124

到目前为止,最好使用 AppCompat.v7 库中的 SwitchCompat。然后,您可以使用简单的样式来更改组件的颜色。

values/themes.xml:

<style name="Theme.MyTheme" parent="Theme.AppCompat.Light">
    <!-- colorPrimary is used for the default action bar background -->
    <item name="colorPrimary">@color/my_awesome_color</item>

    <!-- colorPrimaryDark is used for the status bar -->
    <item name="colorPrimaryDark">@color/my_awesome_darker_color</item>

    <!-- colorAccent is used as the default value for colorControlActivated,
         which is used to tint widgets -->
    <item name="colorAccent">@color/accent</item>

    <!-- You can also set colorControlNormal, colorControlActivated
         colorControlHighlight, and colorSwitchThumbNormal. -->

</style>

参考:Android 开发者博客

编辑

它应该被正确应用的方式是通过android:theme="@style/Theme.MyTheme" ,这也可以应用于父样式,例如 EditTexts、RadioButtons、Switches、CheckBoxes 和 ProgressBars:

<style name="My.Widget.ProgressBar" parent="Widget.AppCompat.ProgressBar">

<style name="My.Widget.Checkbox" parent="Widget.AppCompat.CompoundButton.CheckBox">
于 2014-11-03T10:41:26.633 回答
52

这对我有用(需要 Android 4.1):

Switch switchInput = new Switch(this);
int colorOn = 0xFF323E46;
int colorOff = 0xFF666666;
int colorDisabled = 0xFF333333;
StateListDrawable thumbStates = new StateListDrawable();
thumbStates.addState(new int[]{android.R.attr.state_checked}, new ColorDrawable(colorOn));
thumbStates.addState(new int[]{-android.R.attr.state_enabled}, new ColorDrawable(colorDisabled));
thumbStates.addState(new int[]{}, new ColorDrawable(colorOff)); // this one has to come last
switchInput.setThumbDrawable(thumbStates);

请注意,需要最后添加“默认”状态,如此处所示。

我看到的唯一问题是开关的“拇指”现在看起来比开关的背景或“轨道”大。我认为那是因为我仍在使用默认的轨道图像,它周围有一些空白空间。但是,当我尝试使用这种技术自定义轨道图像时,我的开关似乎有 1 个像素的高度,只出现了一小段开/关文本。必须有解决方案,但我还没有找到它......

安卓 5 更新

在 Android 5 中,上面的代码使开关完全消失。我们应该可以使用新的setButtonTintList方法,但是这似乎被开关忽略了。但这有效:

ColorStateList buttonStates = new ColorStateList(
        new int[][]{
                new int[]{-android.R.attr.state_enabled},
                new int[]{android.R.attr.state_checked},
                new int[]{}
        },
        new int[]{
                Color.BLUE,
                Color.RED,
                Color.GREEN
        }
);
switchInput.getThumbDrawable().setTintList(buttonStates);
switchInput.getTrackDrawable().setTintList(buttonStates);

适用于 Android 6-7 的更新

正如 Cheruby 在评论中所说,我们可以使用新的setThumbTintList并且对我来说按预期工作。我们也可以使用setTrackTintList, 但这会将颜色作为混合应用,结果在深色主题中比预期的要暗,在浅色主题中比预期的要亮,有时甚至到了不可见的程度。在 Android 7 中,我可以通过覆盖 track tint mode来最小化这种变化,但在 Android 6 中我无法获得不错的结果。您可能需要定义额外的颜色来补偿混合。(你有没有觉得 Google 不希望我们自定义应用程序的外观?)

ColorStateList thumbStates = new ColorStateList(
        new int[][]{
                new int[]{-android.R.attr.state_enabled},
                new int[]{android.R.attr.state_checked},
                new int[]{}
        },
        new int[]{
                Color.BLUE,
                Color.RED,
                Color.GREEN
        }
);
switchInput.setThumbTintList(thumbStates);
if (Build.VERSION.SDK_INT >= 24) {
    ColorStateList trackStates = new ColorStateList(
            new int[][]{
                    new int[]{-android.R.attr.state_enabled},
                    new int[]{}
            },
            new int[]{
                    Color.GRAY,
                    Color.LTGRAY
            }
    );
    switchInput.setTrackTintList(trackStates);
    switchInput.setTrackTintMode(PorterDuff.Mode.OVERLAY);
}
于 2014-09-03T02:56:50.323 回答
48

要在不使用 style.xml 或 Java 代码的情况下更改 Switch 样式,您可以将 switch 自定义为布局 XML:

<Switch
        android:id="@+id/checkbox"
        android:layout_width="wrap_content"
        android:thumbTint="@color/blue"
        android:trackTint="@color/white"
        android:checked="true"
        android:layout_height="wrap_content" />

属性android:thumbTintandroid:trackTint允许您自定义颜色

这是此 XML 的视觉结果:

在此处输入图像描述

于 2016-09-14T08:45:44.183 回答
44

作为现有答案的补充:您可以使用res/color文件夹中的选择器自定义拇指和轨道,例如:

switch_track_selector

<?xml version="1.0" encoding="utf-8"?>
<selector
    xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:color="@color/lightBlue"
        android:state_checked="true" />
    <item android:color="@color/grey"/>
</selector>

switch_thumb_selector

<selector
    xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:color="@color/darkBlue"
        android:state_checked="true" />
    <item android:color="@color/white"/>
</selector>

使用这些选择器自定义轨道和拇指色调:

<androidx.appcompat.widget.SwitchCompat
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    app:trackTint="@color/switch_track_selector"
    app:thumbTint="@color/switch_thumb_selector"/>

请记住,如果您对这些属性使用标准Switchandroid命名空间,它仅适用于 API 23 及更高版本,因此请使用SwitchCompat命名app空间xmlns:app="http://schemas.android.com/apk/res-auto"作为通用解决方案。

结果:

在此处输入图像描述

于 2020-06-05T07:06:25.300 回答
37

创建一个自定义 Switch 并覆盖 setChecked 以更改颜色:

  public class SwitchPlus extends Switch {

    public SwitchPlus(Context context) {
        super(context);
    }

    public SwitchPlus(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public SwitchPlus(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    public void setChecked(boolean checked) {
        super.setChecked(checked);
        changeColor(checked);
    }

    private void changeColor(boolean isChecked) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
            int thumbColor;
            int trackColor;

            if(isChecked) {
                thumbColor = Color.argb(255, 253, 153, 0);
                trackColor = thumbColor;
            } else {
                thumbColor = Color.argb(255, 236, 236, 236);
                trackColor = Color.argb(255, 0, 0, 0);
            }

            try {
                getThumbDrawable().setColorFilter(thumbColor, PorterDuff.Mode.MULTIPLY);
                getTrackDrawable().setColorFilter(trackColor, PorterDuff.Mode.MULTIPLY);
            }
            catch (NullPointerException e) {
                e.printStackTrace();
            }
        }
    }
}
于 2015-07-15T18:06:57.220 回答
34
<androidx.appcompat.widget.SwitchCompat
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                app:thumbTint="@color/white"
                app:trackTint="@drawable/checker_track"/>

在 checker_track.xml 里面:

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:color="@color/lightish_blue" android:state_checked="true"/>
    <item android:color="@color/hint" android:state_checked="false"/>
</selector>
于 2019-03-20T16:30:08.943 回答
32

制作可绘制的“newthumb.xml”

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:color="@color/Green" android:state_checked="true"/>
    <item android:color="@color/Red" android:state_checked="false"/>
</selector>

并使可绘制的“newtrack.xml”

<selector xmlns:android="http://schemas.android.com/apk/res/android">
        <item android:color="@color/black" android:state_checked="true"/>
        <item android:color="@color/white" android:state_checked="false"/>
    </selector>

并将其添加到 Switch :

<Switch
        android:trackTint="@drawable/newtrack"
        android:thumbTint="@drawable/newthumb"
         />

此外,只制作一个可绘制文件(“switchcolors.xml”)并将其用于 trackTint 和 thumbTint 也是完全可以的。

于 2019-10-13T09:46:17.577 回答
30

虽然 SubChord 的回答是正确的,但并没有真正回答如何在不影响其他小部件的情况下设置“开启”颜色的问题。为此,请ThemeOverlay在 styles.xml 中使用:

<style name="ToggleSwitchTheme" parent="ThemeOverlay.AppCompat.Light">
    <item name="colorAccent">@color/green_bright</item>
</style>

并在您的交换机中引用它:

<android.support.v7.widget.SwitchCompat
  android:theme="@style/ToggleSwitchTheme" ... />

这样做只会影响您要应用它的视图的颜色。

于 2016-05-25T16:02:01.420 回答
20

当开关状态发生变化时,我通过更新滤色器解决了这个问题......

public void bind(DetailItem item) {
    switchColor(item.toggle);
    listSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
                switchColor(b);
        }
    });
}

private void switchColor(boolean checked) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
        listSwitch.getThumbDrawable().setColorFilter(checked ? Color.BLACK : Color.WHITE, PorterDuff.Mode.MULTIPLY);
        listSwitch.getTrackDrawable().setColorFilter(!checked ? Color.BLACK : Color.WHITE, PorterDuff.Mode.MULTIPLY);
    }
}
于 2015-08-11T18:42:47.020 回答
13

可能有点晚了,但是对于开关按钮,toogle按钮不是答案,您必须更改开关的xml参数中的drawable:

 android:thumb="your drawable here"
于 2013-07-03T22:45:49.543 回答
9

在 Android Lollipop 及更高版本中,在您的主题样式中定义它:

<style name="BaseAppTheme" parent="Material.Theme">
    ...
    <item name="android:colorControlActivated">@color/color_switch</item>
</style>
于 2016-01-28T10:24:56.840 回答
7

创建您自己的 9-patch 图像并将其设置为切换按钮的背景。

http://radleymarx.com/2011/simple-guide-to-9-patch/

于 2012-06-28T22:09:26.023 回答
5

arlomedia 建议的解决方案对我有用。关于他的额外空间问题,我解决了删除所有填充到开关的问题。

编辑

根据要求,这是我所拥有的。

在布局文件中,我的开关位于线性布局内和 TextView 之后。

<LinearLayout
        android:id="@+id/myLinearLayout"
        android:orientation="horizontal"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:layout_gravity="center_horizontal|center"
        android:gravity="right"
        android:padding="10dp"
        android:layout_marginTop="0dp"
        android:background="@drawable/bkg_myLinearLayout"
        android:layout_marginBottom="0dp">
        <TextView
            android:id="@+id/myTextForTheSwitch"
            android:layout_height="wrap_content"
            android:text="@string/TextForTheSwitch"
            android:textSize="18sp"
            android:layout_centerHorizontal="true"
            android:layout_gravity="center_horizontal|center"
            android:gravity="right"
            android:layout_width="wrap_content"
            android:paddingRight="20dp"
            android:textColor="@color/text_white" />
        <Switch
            android:id="@+id/mySwitch"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textOn="@string/On"
            android:textOff="@string/Off"
            android:layout_centerHorizontal="true"
            android:layout_gravity="center_horizontal"
            android:layout_toRightOf="@id/myTextForTheSwitch"
            android:layout_alignBaseline="@id/myTextForTheSwitch"
            android:gravity="right" />
    </LinearLayout>

由于我正在使用 Xamarin / Monodroid(最低 Android 4.1),我的代码是:

Android.Graphics.Color colorOn = Android.Graphics.Color.Green;
Android.Graphics.Color colorOff = Android.Graphics.Color.Gray;
Android.Graphics.Color colorDisabled = Android.Graphics.Color.Green;

StateListDrawable drawable = new StateListDrawable();
drawable.AddState(new int[] { Android.Resource.Attribute.StateChecked }, new ColorDrawable(colorOn));
drawable.AddState(new int[] { -Android.Resource.Attribute.StateEnabled }, new ColorDrawable(colorDisabled));
drawable.AddState(new int[] { }, new ColorDrawable(colorOff));

swtch_EnableEdit.ThumbDrawable = drawable;

swtch_EnableEdit 以前是这样定义的(Xamarin):

Switch swtch_EnableEdit = view.FindViewById<Switch>(Resource.Id.mySwitch);

我没有设置所有填充,也没有调用 .setPadding(0, 0, 0, 0)。

于 2015-02-25T17:36:06.180 回答
5

最简单的方法是定义轨道色调,并将色调模式设置为 src_over 以去除 30% 的透明度。

android:trackTint="@drawable/toggle_style"
android:trackTintMode="src_over"

切换样式.xml

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:color="@color/informationDefault"
        android:state_checked="true"
        />
    <item android:color="@color/textDisabled" android:state_checked="false"/>
</selector>
于 2020-04-28T10:33:08.243 回答
4

您可以为开关小部件制作自定义样式,在为其自定义样式时使用颜色口音作为默认设置

<style name="switchStyle" parent="Theme.AppCompat.Light">
    <item name="colorPrimary">@color/colorPrimary</item>
    <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
    <item name="colorAccent">@color/colorPrimary</item>    <!-- set your color -->
</style>    
于 2017-10-03T07:49:41.753 回答
4

这对我有用-:

1.values /styles.xml中的代码-:

 <style name="SwitchTheme" parent="Theme.AppCompat.Light">
    <item name="android:colorControlActivated">#148E13</item>
</style>

2.在布局文件的开关中添加以下代码行-:

android:theme="@style/SwitchTheme"
于 2020-10-15T18:01:15.713 回答
3

你可以试试这个库,很容易改变开关按钮的颜色。
https://github.com/kyleduo/SwitchButton 在此处输入图像描述

于 2018-07-03T01:39:44.697 回答
1

尝试在这里找到正确的答案:TextView 背景颜色上的选择器。简而言之,您应该在 XML 中创建带有颜色的 Shape,然后在选择器中将其指定为“已选中”状态。

于 2013-07-11T10:06:20.203 回答
1

我不知道如何从 java 中做到这一点,但是如果您为您的应用程序定义了一个样式,您可以在您的样式中添加这一行,您将拥有我使用过的所需颜色 #3F51B5

<color name="ascentColor">#3F51B5</color>
于 2015-03-10T13:07:06.217 回答
1

在 xml 中,您可以将颜色更改为:

 <androidx.appcompat.widget.SwitchCompat
    android:id="@+id/notificationSwitch"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:checked="true"
    app:thumbTint="@color/darkBlue"
    app:trackTint="@color/colorGrey"/>

您可以动态更改为:

Switch.thumbDrawable.setColorFilter(ContextCompat.getColor(requireActivity(), R.color.darkBlue), PorterDuff.Mode.MULTIPLY)
于 2020-07-02T14:45:19.833 回答
0

基于这里的一些答案的组合,这对我有用。

<Switch
    android:trackTintMode="src_over"
    android:thumbTint="@color/white"
    android:trackTint="@color/shadow"
    android:checked="true"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"/>
于 2020-08-16T07:39:35.520 回答
0

更改轨道和拇指可绘制的色调颜色。

switch.getThumbDrawable().setTint(ContextCompat.getColor(this,R.color.colorAccent));

switch.getTrackDrawable().setTint(ContextCompat.getColor(this,R.color.colorAccent));
于 2022-01-29T06:08:36.617 回答
-2

Android Studio 3.6 的解决方案:

yourSwitch.setTextColor(getResources().getColor(R.color.yourColor));

更改颜色 XML 文件定义值 (yourColor) 中 a 的文本颜色。

于 2020-03-09T06:54:37.863 回答