Android 如何从AppCompat库更改SwitchCompat的颜色

Android 如何从AppCompat库更改SwitchCompat的颜色,android,switchcompat,Android,Switchcompat,我的应用程序中有几个不同颜色的开关控件,为了改变它们的颜色,我使用了多个自定义的可绘制选择器 AppCompat v21库的发布引入了一个新的android.support.v7.widget.SwitchCompat控件 是否可以在不使用客户可绘制选择器的情况下,使用XML或代码以编程方式更改SwitchCompat的颜色?AppCompat着色属性: 首先,您应该查看appCompat lib文章以及可以设置的不同属性: colorPrimary:应用程序的主要品牌颜色。默认情况下,这是应用

我的应用程序中有几个不同颜色的开关控件,为了改变它们的颜色,我使用了多个自定义的可绘制选择器

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

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

AppCompat着色属性: 首先,您应该查看appCompat lib文章以及可以设置的不同属性:

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

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

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

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

colorControlActivated:应用于处于激活(例如选中,打开)状态的框架控件的颜色

colorControlHighlight:应用于框架控件高光的颜色(例如涟漪、列表选择器)

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

colorSwitchThumbNormal:应用于处于正常状态的框架开关拇指的颜色。(关闭)


如果单个活动中的所有自定义开关都相同: 使用前面的属性,您可以为每个活动定义自己的主题:

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

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

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

更改SwitchCompat的音轨颜色
多亏了vine'th,我用一个指向SO答案的链接完成了我的答案,该答案解释了如何在道岔关闭时指定轨道的前景。请记住SwitchCompat的已知错误

这是AppCompat上可绘制hdpi中文件损坏的错误

要修复它,只需用这2个文件覆盖它 将其添加到可绘制hdpi的目录中

XML



Java上什么都不需要,所以有些日子我缺少脑细胞,而且:

<android.support.v7.widget.SwitchCompat
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        style="@style/CustomSwitchStyle"/>

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

<android.support.v7.widget.SwitchCompat
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:theme="@style/CustomSwitchStyle"/>


哇。这篇文章让我洞悉了我的错误…希望如果有人偶然发现这一点,它会像我一样帮助他们。感谢Gaëtan Maisse的回答

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


...
@颜色/主题
@颜色/灰色300
@颜色/灰色600
...

in style.xml

<style name="Custom.Widget.SwitchCompat" parent="Widget.AppCompat.CompoundButton.Switch" >
            <item name="android:textColorPrimary">@color/blue</item>  <!--textColor on activated state -->
      </style>

@颜色/蓝色

好的,很抱歉,这些答案大多不完整或有一些小错误。来自@Austin mahoney的非常完整的答案是正确的,也是这个答案的来源,但它很复杂,你可能只想设计一个开关在不同版本的Android上设计“控件”是一件痛苦的事。在一个设计约束非常严格的项目上花了几天的时间后,我终于崩溃了,编写了一个测试应用程序,然后真正深入并测试了各种各样的设计开关和复选框的解决方案,因为当一个设计有一个时,它经常有另一个。这是我发现的

首先:您实际上无法为其中任何一个应用样式,但您可以将一个主题应用于所有主题,或仅应用于其中一个主题

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

第三:当谈到交换机时,如果你想支持旧版本的Android,你有两个基本的选择(我相信你会这样做)

  • 您可以使用
    SwitchCompat
    ,并且可以使它在不同平台上看起来相同
  • 你可以使用
    开关
    ,你可以将它与你的主题的其余部分一起主题化,或者只使用那个特定的开关,在旧版本的Android上,你只会看到一个没有样式的旧方形开关
  • 好了,下面是简单的参考代码。再次,如果你创建一个简单的Hello World!把这段代码放进去,你就可以随心所欲了。所有这些都在这里,所以我将包括活动和样式的XML

    活动\u main.xml

    <?xml version="1.0" encoding="utf-8"?>
    
    
    

    
    

    API_18:


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

    ContextThemeWrapper ctw = ContextThemeWrapper(getActivity(), R.style.Color1SwitchStyle); 
    SwitchCompat sc = new SwitchCompat(ctw)
    
        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
                    }));
        }
    }
    
    每当我想使用
    CustomizedSwitch
    时,我只需在
    xml
    文件中添加一个开关即可

     android:buttonTint="@color/primary"
    

    我同时使用style和android:theme的工作示例(API>=21)

    
    包装内容
    包装内容
    16dp
    真的
    @style/ThemeOverlay.MySwitchCompat
    @颜色/原色暗
    @颜色/文字\u轮廓\u未激活
    #42221F
    
    看起来“colorControlActivated”是我需要的属性,但是如何为每个开关应用它呢?我试图创建扩展材质设计主题并覆盖此属性的自定义主题。然后,我将此主题设置为Switch的样式,但它不起作用。@Orest您是否尝试在清单文件()中定义主题?我尝试了您的示例,但它不起作用。但是如果我使用的是ContextThemeWrapper ctw=ContextThemeWrapper(getActivity(),R.style.Color1SwitchStyle);SwitchCompat sc=新的SwitchCompat(ctw);它起作用了。@YuriHeupa是的,它不起作用
    <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>
    
    <android.support.v7.widget.SwitchCompat
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/adamSwitch"
        android:textColor="@color/top_color"
        android:textAppearance="@color/top_color"
        android:gravity="center"
        app:showText="true"
        app:theme="@style/Custom.Widget.SwitchCompat"
        app:switchPadding="5dp"
        />
    
    <style name="Custom.Widget.SwitchCompat" parent="Widget.AppCompat.CompoundButton.Switch" >
                <item name="android:textColorPrimary">@color/blue</item>  <!--textColor on activated state -->
          </style>
    
    <?xml version="1.0" encoding="utf-8"?>
    
    <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>
    
    <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>
    
        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
                    }));
        }
    }
    
     android:buttonTint="@color/primary"
    
    <android.support.v7.widget.SwitchCompat
        android:id="@+id/wan_enable_nat_switch"
        style="@style/Switch"
        app:layout_constraintBaseline_toBaselineOf="@id/wan_enable_nat_label"
        app:layout_constraintEnd_toEndOf="parent" />
    
    <style name="Switch">
        <item name="android:layout_width">wrap_content</item>
        <item name="android:layout_height">wrap_content</item>
        <item name="android:paddingEnd">16dp</item>
        <item name="android:focusableInTouchMode">true</item>
        <item name="android:theme">@style/ThemeOverlay.MySwitchCompat</item>
    </style>
    
    <style name="ThemeOverlay.MySwitchCompat" parent="">
        <item name="colorControlActivated">@color/colorPrimaryDark</item>
        <item name="colorSwitchThumbNormal">@color/text_outline_not_active</item>
        <item name="android:colorForeground">#42221f1f</item>
    </style>