【问题标题】:How to change the track color of a SwitchCompat如何更改 SwitchCompat 的轨道颜色
【发布时间】:2015-03-06 21:22:22
【问题描述】:

我尝试使用以下链接更改 SwitchCompat 的颜色:

How to change the color of a SwitchCompat

请注意我的开关中的低对比度:

但在更改所有相关颜色值后,SwitchCompat 的轨迹(较亮的灰色)保持不变。除了颜色,我不想改变外观。拇指是粉红色的,我希望轨道有一些对比。我是否错过了在我的 styles.xml 中定义一个值?

我尝试了这些值(随机的非白色):

<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
    <item name="colorPrimary">@color/first</item>
    <item name="colorPrimaryDark">@color/second</item>
    <item name="colorAccent">@color/third</item>
   ...
    <item name="colorControlActivated">@color/first</item>
    <item name="colorControlHighlight">@color/first</item>
    <item name="colorControlNormal">@color/second</item>
    <item name="colorSwitchThumbNormal">@color/second</item>
    <item name="colorButtonNormal">@color/second</item>
...>

【问题讨论】:

    标签: android colors switchcompat


    【解决方案1】:

    使用材料组件库提供的MaterialSwitch

    • 使用 materialThemeOverlay 属性覆盖 Switch 的应用颜色。
      <style name="CustomWidget.MaterialComponents.CompoundButton.Switch" parent="Widget.MaterialComponents.CompoundButton.Switch">
        <item name="materialThemeOverlay">@style/CustomCompoundButton_Switch</item>
      </style>
      <style name="CustomCompoundButton_Switch" >
        <item name="colorSurface">@color/yellow</item>
        <item name="colorOnSurface">@color/orange</item>
        <item name="colorControlActivated">@color/blue</item>
      </style>
    

    在布局中:

    <com.google.android.material.switchmaterial.SwitchMaterial
        style="@style/Widget.MaterialComponents.CompoundButton.Switch"
        ../>
    

    • 使用style 属性:
      <style name="CustomStyleWidget.MaterialComponents.CompoundButton.Switch"
             parent="Widget.MaterialComponents.CompoundButton.Switch">
        <item name="useMaterialThemeColors">false</item>
        <item name="trackTint">@color/track_selector</item>
        <item name="thumbTint">@color/thumb_selector</item>
      </style>
    

    使用 thumb_selector:

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

    和 track_selector:

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

    在布局中:

    <com.google.android.material.switchmaterial.SwitchMaterial
        style="@style/CustomStyleWidget.MaterialComponents.CompoundButton.Switch"
        ../>
    

    【讨论】:

      【解决方案2】:

      以下是开发人员如何更改 SwitchCompat 的可绘制轨迹:
      首先,在根布局中,写xmlns:SwitchCompat="http://schemas.android.com/apk/res-auto"
      然后:

          <android.support.v7.widget.SwitchCompat
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:layout_marginTop="30dp"
              android:thumb="@drawable/your_switch_thumb"
              SwitchCompat:track="@drawable/your_switch_track_selector" 
              />
      

      your_switch_track_selector 可以在哪里:

      <selector xmlns:android="http://schemas.android.com/apk/res/android">
          <item android:drawable="@drawable/switch_ios_track_on" android:state_checked="true" />
          <item android:drawable="@drawable/switch_ios_track_off" android:state_checked="false" />
      </selector>
      
      1.switch_ios_track_on:
      <shape xmlns:android="http://schemas.android.com/apk/res/android"
          android:shape="rectangle"
          >
          <solid android:color="#4EDA62" />
          <corners android:radius="20dp" />
      </shape>
      
      2.switch_ios_track_off:
      <shape xmlns:android="http://schemas.android.com/apk/res/android"
          android:shape="rectangle"
          >
          <solid android:color="#E3E3E3" />
          <corners android:radius="20dp" />
      </shape>
      

      简单易行..

      【讨论】:

        【解决方案3】:

        SwitchCompat 是一个 Material Design 小部件。 当我的活动扩展 AppCompatActivity 并且 android:theme="@style/mySwitch" 工作时。

        【讨论】:

          【解决方案4】:

          如果你想自定义轨道的颜色。你可以使用这个解决方案。

          轨道选择器.xml

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

          checked_color 和 unchecked_color 是您选择的颜色。

          styles.xml

          <style name="mySwitchStyle" parent="@style/Widget.AppCompat.CompoundButton.Switch">
                 <!-- do here for additional costumization on thumb, track background,text appearance -->
          
          
              </style>
          
          
          <style name="mySwitchTheme" parent="ThemeOverlay.AppCompat.Light">
                  <item name="switchStyle">@style/mySwitchStyle</item>
                  <item name="colorControlActivated">@color/red</item>
                  <item name="colorControlNormal">@color/colorAccent</item>
                  <item name="trackTint">@color/track_selector</item>
              </style>
          

          布局文件

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

          【讨论】:

          • 有用的解决方案
          【解决方案5】:

          只需使用 colorControlActivated 来设置 SwitchCompat 的轨道和拇指的颜色。

          如果没有设置,默认的 colorControlActivated 颜色将使用 colorAccent。 (从经验来看,还是找不到源代码在哪里)。

          源代码变了,还是不像@Ovidiu说的那样。 不过还是感谢他让我知道从源代码中找到答案。

          mThumbDrawable = a.getDrawable(R.styleable.SwitchCompat_android_thumb);
          

          最终会调用下面的方法。

          /frameworks/support/v7/appcompat/src/android/support/v7/widget/AppCompatDrawableManager.java

          private ColorStateList createSwitchTrackColorStateList(Context context) {
              final int[][] states = new int[3][];
              final int[] colors = new int[3];
              int i = 0;
          
              // Disabled state
              states[i] = ThemeUtils.DISABLED_STATE_SET;
              colors[i] = getThemeAttrColor(context, android.R.attr.colorForeground, 0.1f);
              i++;
          
              states[i] = ThemeUtils.CHECKED_STATE_SET;
              colors[i] = getThemeAttrColor(context, R.attr.colorControlActivated, 0.3f);
              i++;
          
              // Default enabled state
              states[i] = ThemeUtils.EMPTY_STATE_SET;
              colors[i] = getThemeAttrColor(context, android.R.attr.colorForeground, 0.3f);
              i++;
          
              return new ColorStateList(states, colors);
          }
          
          private ColorStateList createSwitchThumbColorStateList(Context context) {
              final int[][] states = new int[3][];
              final int[] colors = new int[3];
              int i = 0;
          
              final ColorStateList thumbColor = getThemeAttrColorStateList(context,
                      R.attr.colorSwitchThumbNormal);
          
              if (thumbColor != null && thumbColor.isStateful()) {
                  // If colorSwitchThumbNormal is a valid ColorStateList, extract the default and
                  // disabled colors from it
          
                  // Disabled state
                  states[i] = ThemeUtils.DISABLED_STATE_SET;
                  colors[i] = thumbColor.getColorForState(states[i], 0);
                  i++;
          
                  states[i] = ThemeUtils.CHECKED_STATE_SET;
                  colors[i] = getThemeAttrColor(context, R.attr.colorControlActivated);
                  i++;
          
                  // Default enabled state
                  states[i] = ThemeUtils.EMPTY_STATE_SET;
                  colors[i] = thumbColor.getDefaultColor();
                  i++;
              } else {
                  // Else we'll use an approximation using the default disabled alpha
          
                  // Disabled state
                  states[i] = ThemeUtils.DISABLED_STATE_SET;
                  colors[i] = getDisabledThemeAttrColor(context, R.attr.colorSwitchThumbNormal);
                  i++;
          
                  states[i] = ThemeUtils.CHECKED_STATE_SET;
                  colors[i] = getThemeAttrColor(context, R.attr.colorControlActivated);
                  i++;
          
                  // Default enabled state
                  states[i] = ThemeUtils.EMPTY_STATE_SET;
                  colors[i] = getThemeAttrColor(context, R.attr.colorSwitchThumbNormal);
                  i++;
              }
          
              return new ColorStateList(states, colors);
          }
          

          【讨论】:

            【解决方案6】:
             Here is Switch Layout
             -Adding theme to your switch to change the color of track.Check the style given below:-.
            
            **Switch Compact**
              <android.support.v7.widget.SwitchCompat
                            android:id="@+id/goOnlineBtn"
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            app:theme="@style/Switch_style/>
            
            
            **Switch_style**
               <style name="Switch_style" parent="Theme.AppCompat.Light">
                    <!-- active thumb & track color (30% transparency) -->
                    <item name="colorControlNormal">@android:color/white</item>
                    <item name="colorControlActivated">@android:color/blue</item>
                    <item name="colorSwitchThumbNormal">@android:color/white</item>
                    <item name="trackTint">@color/white</item>
               </style>
            

            trackTint 会在哪里改变你的轨道颜色

            【讨论】:

              【解决方案7】:

              我遇到了同样的问题。最后用这个 Kotlin 代码以编程方式解决了它

              fun tintSwitchButton(sw: SwitchCompat, resolvedColor: Int) {
                  val states = arrayOf(
                          intArrayOf(-android.R.attr.state_pressed),
                          intArrayOf(android.R.attr.state_pressed)
                  )
              
                  DrawableCompat.setTintList(sw?.trackDrawable, ColorStateList(
                          states,
                          intArrayOf(resolvedColor, resolvedColor)
                  ))
              
                  DrawableCompat.setTintList(sw?.thumbDrawable, ColorStateList(
                          states,
                          intArrayOf(Color.WHITE, Color.WHITE)
                  ))
              }
              

              而函数调用是

              tintSwitchButton(switchCompat, Color.rgb(214, 0, 0))
              

              你也可以创建一个扩展函数:

              fun SwitchCompat.tint(resolvedColor: Int) {
                  val states = arrayOf(
                      intArrayOf(-android.R.attr.state_pressed),
                      intArrayOf(android.R.attr.state_pressed)
                  )
              
                  DrawableCompat.setTintList(trackDrawable, ColorStateList(
                      states,
                      intArrayOf(resolvedColor, resolvedColor)
                  ))
              
                  DrawableCompat.setTintList(thumbDrawable, ColorStateList(
                      states,
                      intArrayOf(Color.WHITE, Color.WHITE)
                  ))
              }
              

              这样通话会更容易

              switchCompat.tint(Color.rgb(214,0,0))
              

              【讨论】:

                【解决方案8】:

                如果您想在一个 Activity 中使用多种颜色进行更多开关,可以使用此解决方案(基于 @Konifar 的主题):

                <style name="CustomSwitchTheme" parent="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
                    <!-- Active thumb color & Active track color(30% transparency) -->
                    <item name="colorControlActivated">@color/custom</item>
                    <!-- Inactive thumb color -->
                    <item name="colorSwitchThumbNormal">#E0E0E0</item>
                    <!-- Inactive track color(30% transparency) -->
                    <item name="android:colorForeground">#757575</item>
                </style>
                

                @color/custom 是开关激活时的拇指颜色。

                然后以这种方式将此主题应用于您的 SwitchCompat:

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

                【讨论】:

                • androidx.appcompat.widget.SwitchCompat - 迁移到 androidX 时无法更改
                【解决方案9】:

                以下是针对特定 SwitchCompat编程方式 更改轨道和拇指颜色的 AppCompat 方法。对于此示例,我已将 thumbColor 硬编码为红色。理想情况下,您可以通过第二个方法参数设置颜色。

                请注意,当开关被选中时,会显示一个波纹。下面的代码不会改变波纹颜色。

                public static void setSwitchColor(SwitchCompat v) {
                    // thumb color of your choice
                    int thumbColor = Color.RED;
                
                    // trackColor is the thumbColor with 30% transparency (77)
                    int trackColor = Color.argb(77, Color.red(thumbColor), Color.green(thumbColor), Color.blue(thumbColor));
                
                    // setting the thumb color
                    DrawableCompat.setTintList(v.getThumbDrawable(), new ColorStateList(
                            new int[][]{
                                    new int[]{android.R.attr.state_checked},
                                    new int[]{}
                            },
                            new int[]{
                                    thumbColor,
                                    Color.WHITE
                            }));
                
                    // setting the track color
                    DrawableCompat.setTintList(v.getTrackDrawable(), new ColorStateList(
                            new int[][]{
                                    new int[]{android.R.attr.state_checked},
                                    new int[]{}
                            },
                            new int[]{
                                    trackColor,
                                    Color.parseColor("#4D000000") // full black with 30% transparency (4D)
                            }));
                }
                

                【讨论】:

                  【解决方案10】:

                  我遇到了同样的问题并解决了。

                  <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.internal.widget.TintManager.java

                  private ColorStateList getSwitchTrackColorStateList() {
                      if (mSwitchTrackStateList == null) {
                          final int[][] states = new int[3][];
                          final int[] colors = new int[3];
                          int i = 0;
                  
                          // Disabled state
                          states[i] = new int[] { -android.R.attr.state_enabled };
                          colors[i] = getThemeAttrColor(android.R.attr.colorForeground, 0.1f);
                          i++;
                  
                          states[i] = new int[] { android.R.attr.state_checked };
                          colors[i] = getThemeAttrColor(R.attr.colorControlActivated, 0.3f);
                          i++;
                  
                          // Default enabled state
                          states[i] = new int[0];
                          colors[i] = getThemeAttrColor(android.R.attr.colorForeground, 0.3f);
                          i++;
                  
                          mSwitchTrackStateList = new ColorStateList(states, colors);
                      }
                      return mSwitchTrackStateList;
                  }
                  

                  【讨论】:

                  • 有什么方法可以设置不同的活动拇指颜色和活动轨道颜色?而不是相同颜色的 30% 透明度差异。
                  • @ir2pid : 你可以指定一个drawable。
                  • 我在同一个活动中有多个开关,如何为每个开关设置不同的颜色???
                  • 介意我问你是如何阅读源代码的?我下载了源代码,但没有发现任何关于这个类的信息。你是通过这个链接阅读的吗:android.googlesource.com/platform/frameworks/support/+/… 能否也分享一些阅读源代码的经验或方法?
                  • androidx.appcompat.widget.SwitchCompat 怎么办?我完全不能挂起样式?
                  猜你喜欢
                  • 2020-03-27
                  • 1970-01-01
                  • 2017-10-10
                  • 1970-01-01
                  • 2018-02-07
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  相关资源
                  最近更新 更多