android - style - Cómo cambiar el color de la pista de un SwitchCompat
switch style android studio (10)
Intenté usar el siguiente enlace para cambiar el color de un SwitchCompat:
Cómo cambiar el color de un SwitchCompat
Observe la baja restricción en mi interruptor:
Pero después de cambiar todos los valores de color relevantes, la pista (el gris más brillante) de SwitchCompat sigue siendo la misma. No quiero cambiar la apariencia excepto el color. El pulgar está en rosa y quiero que la pista tenga algo de contraste. ¿Olvidé definir un valor en mi styles.xml?
Probé estos valores (colores no blancos aleatorios):
<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>
...>
A continuación se muestra la forma de
AppCompat
de cambiar tanto la pista como el color del pulgar mediante
programación
, para un
SwitchCompat
específico.
Para este ejemplo, he codificado el
thumbColor
a rojo.
Idealmente, establecería el color a través de un segundo parámetro de método.
Tenga en cuenta que cuando se marca el interruptor, se muestra una onda. El código de abajo no cambiará el color de ondulación.
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)
}));
}
Así es como un desarrollador puede cambiar la pista dibujable de un SwitchCompat:
Primero, en el diseño raíz, escriba
xmlns:SwitchCompat="http://schemas.android.com/apk/res-auto"
Entonces:
<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"
/>
donde your_switch_track_selector puede ser:
<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>
Simple y fácil..
Con el
MaterialSwitch
provisto por la Biblioteca de Componentes de Materiales.
-
Use el atributo
materialThemeOverlay
para anular el color de la aplicación para el 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>
Y en el diseño:
<com.google.android.material.switchmaterial.SwitchMaterial style="@style/Widget.MaterialComponents.CompoundButton.Switch" ../>
-
Use el atributo de
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>
con 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>
y 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>
Y en el diseño:
<com.google.android.material.switchmaterial.SwitchMaterial style="@style/CustomStyleWidget.MaterialComponents.CompoundButton.Switch" ../>
Estaba teniendo el mismo problema. Finalmente lo resolvió programáticamente con este código de 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)
))
}
Y la llamada a la función es
tintSwitchButton(switchCompat, Color.rgb(214, 0, 0))
También puede crear una función de extensión:
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)
))
}
Entonces la llamada sería más fácil
switchCompat.tint(Color.rgb(214,0,0))
Si desea más interruptores en varios colores en una Actividad, puede usar esta solución (basada en el tema de @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>
donde
@color/custom
es el color del pulgar cuando se activa el interruptor.
Luego aplique este tema a su SwitchCompat de esta manera:
<android.support.v7.widget.SwitchCompat
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:theme="@style/CustomSwitchTheme" />
Si desea personalizar el color de la pista, puede usar esta solución.
track selector.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" />
donde check_color y unchecked_color son el color de sus elecciones.
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>
archivo de diseño
<android.support.v7.widget.SwitchCompat
android:theme="@style/mySwitchTheme"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
SwitchCompat es un widget de diseño de materiales. cuando mi actividad extiende AppCompatActivity y android: theme = "@ style / mySwitch" funciona.
Tuve el mismo problema y lo resolví.
<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>
Leo el código de compatibilidad de la aplicación y lo entiendo.
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;
}
simplemente use colorControlActivated para establecer el color de la pista y el pulgar de SwitchCompat.
Si no se establece, el color predeterminado ColorControlActivated usará colorAccent. (según la experiencia, todavía no encuentro en qué parte del código fuente).
El código fuente cambió y todavía no le gusta, dijo @Ovidiu. Pero aún así le agradezco por avisarme para encontrar la respuesta del código fuente.
mThumbDrawable = a.getDrawable(R.styleable.SwitchCompat_android_thumb);
eventualmente llamará al siguiente método.
/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);
}
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>
Donde trackTint cambiará el color de tu pista