J'ai quelques commutateurs avec des couleurs différentes dans mon application et pour changer leurs couleurs, j'ai utilisé un sélecteur personnalisable pour chaque commutateur.
Lorsque la nouvelle bibliothèque AppCompat v21 a été publiée, un nouveau contrôle Android.support.v7.widget.SwitchCompat existait.
Est-il possible de changer la couleur d'un SwitchCompat sans utiliser de dessin, par exemple en utilisant XML ou du code?
Ok, alors je suis désolé mais la plupart de ces réponses sont incomplètes ou ont un bug mineur. La réponse très complète de @ austyn-mahoney est correcte et constitue la source de cette réponse, mais elle est compliquée et vous souhaitez probablement simplement styler un commutateur. Le «style» des commandes à travers différentes versions d’Android est une épopée douleur dans le cul. Après avoir tiré mes cheveux pendant des jours sur un projet avec des contraintes de conception très strictes, je suis finalement tombé en panne et j'ai écrit une application de test. il a souvent l'autre. Voici ce que j'ai trouvé ...
_ {First: Vous ne pouvez en réalité styliser aucun d'entre eux, mais vous pouvez appliquer un thème à chacun d'entre eux, ou à un seul d'entre eux.
Second: Vous pouvez tout faire à partir de XML et vous n'avez pas besoin d'un second value-v21/styles.xml.
Third: en ce qui concerne les commutateurs, vous avez le choix entre deux options de base si vous souhaitez prendre en charge les anciennes versions d'Android (comme vous le savez sûrement) ...
SwitchCompat
et vous pourrez lui donner la même apparence sur toutes les plateformes.Switch
et vous pourrez la thématiser avec le reste de votre thème ou simplement avec ce commutateur particulier. Sur les anciennes versions d'Android, vous verrez simplement un commutateur carré plus ancien et sans style.Ok maintenant pour le code de référence simple. Encore une fois si vous créez un simple Hello World! et déposez ce code dans vous pouvez jouer au contenu de votre coeur. Tout cela est une plaque chauffante ici, donc je vais simplement inclure le code XML pour l'activité et le style ...
activity_main.xml ...
<?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>
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>
Je sais, je sais, vous êtes trop paresseux pour construire cela, vous voulez juste obtenir votre code écrit et l'enregistrer afin que vous puissiez fermer cette douleur dans le cul bug de cauchemar de compatibilité Android afin que le concepteur de votre équipe soit enfin heureux . J'ai compris. Voici à quoi ça ressemble quand vous le lancez ...
API_21:
API_18:
Je pense que la réponse dans le lien ci-dessous est meilleure
Comment changer la couleur de la piste d'un 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>
Ainsi, certains jours, je manque de cellules cérébrales et:
<Android.support.v7.widget.SwitchCompat
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
style="@style/CustomSwitchStyle"/>
n'applique pas le thème car le style est incorrect. Je devais utiliser app: theme: P
<Android.support.v7.widget.SwitchCompat
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
app:theme="@style/CustomSwitchStyle"/>
Whoopsies. C'est ce message qui m'a permis de comprendre mon erreur. Espérons que si quelqu'un tombe par hasard dessus, cela l'aidera comme il l'a fait pour moi. Merci Gaëtan Maisse pour ta réponse
Soyez attentif au bogue connu avec SwitchCompat
C'est un bug avec un fichier corrompu dans drawable-hdpi sur AppCompat https://code.google.com/p/Android/issues/detail?id=78262
Pour le résoudre, remplacez-le simplement avec ces 2 fichiers https://github.com/lopespm/quick-fix-switchcompat-resources .__ Ajoutez-le dans votre répertoire drawable-hdpi
XML
<Android.support.v7.widget.SwitchCompat
Android:id="@+id/dev_switch_show_dev_only"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
/>
Et rien n'était nécessaire sur Java
<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"
/>
dans style.xml
<style name="Custom.Widget.SwitchCompat" parent="Widget.AppCompat.CompoundButton.Switch" >
<item name="Android:textColorPrimary">@color/blue</item> <!--textColor on activated state -->
</style>
Pour avoir un meilleur contrôle de la couleur de la piste (aucun changement d'alpha API
contrôlé), j'ai étendu SwitchCompat
et style les éléments par programme:
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
}));
}
}
Chaque fois que je veux utiliser la variable CustomizedSwitch
, j'en ajoute simplement une à mon fichier xml
.
Juste
Android:buttonTint="@color/primary"
Mon exemple de travail d'utilisation simultanée de style et d'Android: thème (API> = 21)
<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>