如何从AppCompat库更改SwitchCompat的颜色

Ore*_*est 124 android switchcompat

我的应用程序中有一些不同颜色的开关控件,并且我使用多个自定义可绘制选择器来更改颜色.

随着AppCompat v21库的发布,引入了一个新的android.support.v7.widget.SwitchCompat控件.

是否可以在没有客户可绘制选择器的情况下以编程方式更改SwitchCompat的颜色,但是使用XML或代码?

Gaë*_* M. 320

AppCompat着色属性:

首先,你应该去看一下程序兼容性LIB文章存在,并可以设置不同的attributs:

colorPrimary:应用程序的主要品牌颜色.默认情况下,这是应用于操作栏背景的颜色.

colorPrimaryDark:主要品牌颜色的深色变体.默认情况下,这是应用于状态栏(通过statusBarColor)和导航栏(通过navigationBarColor)的颜色.

colorAccent:主要品牌颜色的明亮补充.默认情况下,这是应用于框架控件的颜色(通过colorControlActivated).

colorControlNormal:应用于框架控件的颜色处于正常状态.

colorControlActivated:在激活(例如,已检查,打开)状态下应用于框架控件的颜色.

colorControlHighlight:应用于框架控件的颜色突出显示(例如涟漪,列表选择器).

colorButtonNormal:在正常状态下应用于框架按钮的颜色.

colorSwitchThumbNormal:应用于框架的颜色在正常状态下切换拇指.(关掉)


如果单个活动中的所有自定义开关都相同:

使用以前的attributs,您可以为每个活动定义自己的主题:

<style name="Theme.MyActivityTheme" 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>
Run Code Online (Sandbox Code Playgroud)

并且:

<manifest>
...
    <activity
        android:name=".MainActivity" 
        android:theme="@style/Theme.MyActivityTheme">
    </activity>
...
</manifest>
Run Code Online (Sandbox Code Playgroud)

如果要在单个活动中使用不同的自定义开关:

由于appcompat中的小部件着色通过拦截任何布局膨胀并在其位置插入特定的色调感知版本的小部件来工作(请参阅Chris Banes 关于它的帖子),您不能将自定义样式应用于布局xml文件的每个开关.您必须设置一个自定义上下文,它将使用正确的颜色着色切换.

-

要在5.0之前执行此操作,您需要创建一个使用海关属性覆盖全局主题的上下文,然后以编程方式创建交换机:

ContextThemeWrapper ctw = ContextThemeWrapper(getActivity(), R.style.Color1SwitchStyle); 
SwitchCompat sc = new SwitchCompat(ctw)
Run Code Online (Sandbox Code Playgroud)

从AppCompat开始,v22.1您可以使用以下XML命令将主题应用于切换小部件:

<RelativeLayout
    xmlns:app="http://schemas.android.com/apk/res-auto"
    ...>

    <android.support.v7.widget.SwitchCompat
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:theme="@style/Color1SwitchStyle"/>
Run Code Online (Sandbox Code Playgroud)

您的自定义切换主题:

<style name="Color1SwitchStyle">
    <item name="colorControlActivated">@color/my_awesome_color</item>
</style>
Run Code Online (Sandbox Code Playgroud)

-

Android 5.0上,它看起来像一个新的视图attribut来生活:( android:theme与清单中的活动声明的一个用途相同).基于另一个Chris Banes的帖子,后者你应该可以直接在布局xml的视图上定义一个自定义主题:

<android.support.v7.widget.SwitchCompat
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:theme="@style/Color1SwitchStyle"/>
Run Code Online (Sandbox Code Playgroud)

更改SwitchCompat的轨道颜色

感谢Vine'th,我通过一个SO答案的链接完成我的答案,该链接解释了当Switch关闭时如何指定轨道的前景,它就在那里.

  • 看起来“colorControlActivated”是我需要的属性,但是如何将它应用于每个开关?我尝试创建自定义主题来扩展我的材料设计主题并覆盖此属性。然后我将这个主题设置为 Switch 的样式,但它不起作用。 (2认同)

Aar*_*ley 61

好的,所以我很抱歉,但大部分答案都不完整或者有一些小错误.来自@ austyn-mahoney的完整答案是正确的,也是这个答案的来源,但它很复杂,你可能只想设置一个开关.跨越不同版本的Android的"样式"控件是一个史诗般的痛苦.在一个项目设计受到严格限制的情况下拔掉头发几天之后,我终于崩溃并编写了一个测试应用程序然后真正挖掘并测试了各种解决方案,用于样式开关和复选框,因为当一个设计有一个它经常有另一个.这是我发现的......

第一:你实际上不能设置其中任何一个,但你可以将一个主题应用于所有这些,或者只是其中一个.

第二:您可以从XML完成所有操作,而不需要第二个值-v21/styles.xml.

第三:当涉及到交换机时,如果你想支持旧版本的Android(比如我确定你这样做),你有两个基本的选择......

  1. 您可以使用a,SwitchCompat并且您可以使它在不同平台上看起来相同.
  2. 你可以使用a Switch,你可以用你的主题的其余部分来主题,或者只是那个特定的开关,在旧版本的Android上,你只会看到一个没有样式的旧方形开关.

现在好了,简单的参考代码.再次,如果您创建一个简单的Hello World!并删除此代码,你可以发挥你的心灵内容.所有这些都是锅炉板,所以我只是要包含活动和风格的XML ......

activity_main.xml中...

<?xml version="1.0" encoding="utf-8"?>
Run Code Online (Sandbox Code Playgroud)

<RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.kunai.switchtest.MainActivity">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="'Styled' SwitchCompat" />

    <android.support.v7.widget.SwitchCompat
        android:id="@+id/switch_item"
        android:layout_width="wrap_content"
        android:layout_height="46dp"
        android:layout_alignParentEnd="true"
        android:layout_marginEnd="16dp"
        android:checked="true"
        android:longClickable="false"
        android:textOff="OFF"
        android:textOn="ON"
        app:switchTextAppearance="@style/BrandedSwitch.text"
        app:theme="@style/BrandedSwitch.control"
        app:showText="true" />

</RelativeLayout>

<RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.kunai.switchtest.MainActivity">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Themed SwitchCompat" />

    <android.support.v7.widget.SwitchCompat
        android:id="@+id/switch_item2"
        android:layout_width="wrap_content"
        android:layout_height="46dp"
        android:layout_alignParentEnd="true"
        android:layout_marginEnd="16dp"
        android:checked="true"
        android:longClickable="false" />

</RelativeLayout>

<RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.kunai.switchtest.MainActivity">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Themed Switch" />

    <Switch
        android:id="@+id/switch_item3"
        android:layout_width="wrap_content"
        android:layout_height="46dp"
        android:layout_alignParentEnd="true"
        android:layout_marginEnd="16dp"
        android:checked="true"
        android:longClickable="false"
        android:textOff="OFF"
        android:textOn="ON"/>

</RelativeLayout>

<RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.kunai.switchtest.MainActivity">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="'Styled' Switch" />

    <Switch
        android:id="@+id/switch_item4"
        android:layout_width="wrap_content"
        android:layout_height="46dp"
        android:layout_alignParentEnd="true"
        android:layout_marginEnd="16dp"
        android:checked="true"
        android:longClickable="false"
        android:textOff="OFF"
        android:textOn="ON"
        android:theme="@style/BrandedSwitch"/>

</RelativeLayout>

<RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.kunai.switchtest.MainActivity">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="'Styled' CheckBox" />

    <CheckBox
        android:id="@+id/checkbox"
        android:layout_width="wrap_content"
        android:layout_height="46dp"
        android:layout_alignParentEnd="true"
        android:layout_marginEnd="16dp"
        android:checked="true"
        android:longClickable="false"
        android:theme="@style/BrandedCheckBox"/>

</RelativeLayout>

<RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.kunai.switchtest.MainActivity">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Themed CheckBox" />

    <CheckBox
        android:id="@+id/checkbox2"
        android:layout_width="wrap_content"
        android:layout_height="46dp"
        android:layout_alignParentEnd="true"
        android:layout_marginEnd="16dp"
        android:checked="true"
        android:longClickable="false"/>

</RelativeLayout>
Run Code Online (Sandbox Code Playgroud)

styles.xml ...

<resources>

<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
    <!-- Customize your theme here. -->
    <item name="colorPrimary">#3F51B5</item>
    <item name="colorPrimaryDark">#303F9F</item>
    <item name="colorAccent">#FF4081</item>
</style>

<style name="BrandedSwitch.control" parent="Theme.AppCompat.Light">
    <!-- active thumb & track color (30% transparency) -->
    <item name="colorControlActivated">#e6e600</item>
    <item name="colorSwitchThumbNormal">#cc0000</item>
</style>

<style name="BrandedSwitch.text" parent="Theme.AppCompat.Light">
    <item name="android:textColor">#ffa000</item>
    <item name="android:textSize">9dp</item>
</style>

<style name="BrandedCheckBox" parent="AppTheme">
    <item name="colorAccent">#aaf000</item>
    <item name="colorControlNormal">#ff0000</item>
</style>

<style name="BrandedSwitch" parent="AppTheme">
    <item name="colorAccent">#39ac39</item>
</style>
Run Code Online (Sandbox Code Playgroud)

我知道,我知道,你太懒于构建它,你只是想编写你的代码并检查它,这样你就可以在Android兼容性噩梦bug中消除这种痛苦,这样你团队中的设计师就会很开心.我知道了.这是你运行时的样子......

API_21:

API 21

API_18:

API18

  • 最有用的答案.谢谢. (2认同)
  • 迁移到 androidx.appcompat.widget.SwitchCompat - 主题不起作用 (2认同)

小智 13

我认为以下链接中的答案更好

如何更改SwitchCompat的轨道颜色

<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
   ...
   <!-- Active thumb color & Active track color(30% transparency) -->
   <item name="colorControlActivated">@color/theme</item>
   <!-- Inactive thumb color -->
   <item name="colorSwitchThumbNormal">@color/grey300</item>
   <!-- Inactive track color(30% transparency) -->
   <item name="android:colorForeground">@color/grey600</item>
   ...
</style>
Run Code Online (Sandbox Code Playgroud)


isu*_*hes 6

所以有些日子我缺乏脑细胞和:

<android.support.v7.widget.SwitchCompat
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        style="@style/CustomSwitchStyle"/>
Run Code Online (Sandbox Code Playgroud)

不适用主题因为样式不正确.我应该使用app:theme:P

<android.support.v7.widget.SwitchCompat
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:theme="@style/CustomSwitchStyle"/>
Run Code Online (Sandbox Code Playgroud)

Whoopsies.这篇文章让我深入了解了我的错误...希望如果有人偶然发现它会帮助他们像我一样.谢谢GaëtanMaisse的回答


Tom*_*ard 5

为了更好地控制轨道颜色(没有API受控的 alpha 变化),我SwitchCompat以编程方式扩展和设置元素的样式:

    public class CustomizedSwitch extends SwitchCompat {

    public CustomizedSwitch(Context context) {
        super(context);
        initialize(context);
    }

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

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

    public void initialize(Context context) {
        // DisplayMeasurementConverter is just a utility to convert from dp to px and vice versa
        DisplayMeasurementConverter displayMeasurementConverter = new DisplayMeasurementConverter(context);
        // Sets the width of the switch
        this.setSwitchMinWidth(displayMeasurementConverter.dpToPx((int) getResources().getDimension(R.dimen.tp_toggle_width)));
        // Setting up my colors
        int mediumGreen = ContextCompat.getColor(context, R.color.medium_green);
        int mediumGrey = ContextCompat.getColor(context, R.color.medium_grey);
        int alphaMediumGreen = Color.argb(127, Color.red(mediumGreen), Color.green(mediumGreen), Color.blue(mediumGreen));
        int alphaMediumGrey = Color.argb(127, Color.red(mediumGrey), Color.green(mediumGrey), Color.blue(mediumGrey));
        // Sets the tints for the thumb in different states
        DrawableCompat.setTintList(this.getThumbDrawable(), new ColorStateList(
                new int[][]{
                        new int[]{android.R.attr.state_checked},
                        new int[]{}
                },
                new int[]{
                        mediumGreen,
                        ContextCompat.getColor(getContext(), R.color.light_grey)
                }));
        // Sets the tints for the track in different states
        DrawableCompat.setTintList(this.getTrackDrawable(), new ColorStateList(
                new int[][]{
                        new int[]{android.R.attr.state_checked},
                        new int[]{}
                },
                new int[]{
                        alphaMediumGreen,
                        alphaMediumGrey
                }));
    }
}
Run Code Online (Sandbox Code Playgroud)

每当我想使用 时CustomizedSwitch,我只需在我的xml文件中添加一个。