Изменить «вкл» цвет переключателя


156

Я использую стандартный элемент управления Switch с темой holo.light в приложении ICS.

Я хочу изменить выделенный цвет или цвет состояния кнопки переключения со стандартного голубого на зеленый.

Это должно быть легко, но я не могу понять, как это сделать.


На самом деле я не вижу другого способа, кроме как скопировать соответствующие ресурсы платформы (файлы селектора и * .png) и изменить отображаемое состояние «включено». Не забудьте Switchпотом указать на этот пользовательский селектор.
— МХ.

Ответы:


101

На данный момент лучше использовать SwitchCompat из библиотеки AppCompat.v7. Затем вы можете использовать простой стиль, чтобы изменить цвет ваших компонентов.

values/themes.xml:

<style name="Theme.MyTheme" 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>

ref: Блог разработчиков Android

РЕДАКТИРОВАТЬ :

Способ его правильного применения является сквозным, android:theme="@style/Theme.MyTheme" а также его можно применять к родительским стилям, таким как EditTexts, RadioButtons, Switches, CheckBoxes и ProgressBars:

<style name="My.Widget.ProgressBar" parent="Widget.AppCompat.ProgressBar">

<style name="My.Widget.Checkbox" parent="Widget.AppCompat.CompoundButton.CheckBox">

1
Хотя это не применимо в то время, это должен быть принятый ответ!
— Эндрю Галлаш

Изменили это на принятый ответ, так как кажется более «современный» подход к этому вопросу.
— JamesSugrue

1
Я попробовал все это, и ни один из них не изменил цвет состояния «включено» для моего переключателя.
— Адам Джонс

31
«включен» есть colorAccent, «выключен» есть colorSwitchThumbNormal. При использовании AppCompatтемы, вы должны использовать, SwitchCompatа не Switch. Если вы используете SDK 23+, вы можете использовать android:thumbTintи android:thumbTintModeс ColorStateList.
— Том

1
@Tom plz ответит, что эти 'android: thumbTint' вещи будут работать на устройствах <23
— Шириш Хервейд

269

Поздно на вечеринку, но я так и сделал

Стиль

 <style name="SCBSwitch" parent="Theme.AppCompat.Light">
        <!-- active thumb & track color (30% transparency) -->
        <item name="colorControlActivated">#46bdbf</item>

        <!-- inactive thumb color -->
        <item name="colorSwitchThumbNormal">#f1f1f1
        </item>

        <!-- inactive track color (30% transparency) -->
        <item name="android:colorForeground">#42221f1f
        </item>
    </style>

Цвета

введите описание изображения здесь

раскладка

<android.support.v7.widget.SwitchCompat
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentRight="true"
    android:checked="false"
    android:theme="@style/SCBSwitch" />

результат

См изменение цвета для включения и выключения переключателя

введите описание изображения здесь


14
@MaksimKniazev Вы должны использовать SwitchCompat;)
— Ovi Trif

1
Хорошо, за исключением colorControlActivation - он не устанавливает цвет дорожки, только цвет большого пальца.
— Указатель нулевой

1
Вот решение для Switch и SwitchCompat: stackoverflow.com/a/47036089/5869630
— roghayeh hosseini

Теги <style> должны быть записаны в res >> values ​​>> styles.xml и на странице XML для <Switch ...> вы должны добавить только строку с именем: android: theme = "@ style / SCBSwitch, и мои цвета : colorControlActivation "> # ff0000 and colorSwitchThumbNormal"> # 00ff00 android: colorForeground "> # 00ff00
— Залив

@OviTrif Отлично! Впечатляет, как трудно найти такую ​​простую информацию. Много-много ответов я читал, и никто до сих пор не дал рабочего ответа. В заключение!
— jairhumberto

49

Это работает для меня (требуется Android 4.1):

Switch switchInput = new Switch(this);
int colorOn = 0xFF323E46;
int colorOff = 0xFF666666;
int colorDisabled = 0xFF333333;
StateListDrawable thumbStates = new StateListDrawable();
thumbStates.addState(new int[]{android.R.attr.state_checked}, new ColorDrawable(colorOn));
thumbStates.addState(new int[]{-android.R.attr.state_enabled}, new ColorDrawable(colorDisabled));
thumbStates.addState(new int[]{}, new ColorDrawable(colorOff)); // this one has to come last
switchInput.setThumbDrawable(thumbStates);

Обратите внимание, что состояние «по умолчанию» должно быть добавлено последним, как показано здесь.

Единственная проблема, которую я вижу, состоит в том, что «большой палец» переключателя теперь кажется больше, чем фон или «дорожка» переключателя. Я думаю, это потому, что я все еще использую изображение дорожки по умолчанию, вокруг которого есть свободное место. Однако, когда я попытался настроить изображение дорожки, используя эту технику, мой переключатель, как оказалось, имел высоту 1 пиксель с появлением лишь небольшого количества включенного / выключенного текста. Должно быть решение для этого, но я еще не нашел его ...

Обновление для Android 5

В Android 5 приведенный выше код заставляет переключатель полностью исчезнуть. Мы должны иметь возможность использовать новый метод setButtonTintList , но, похоже, это игнорируется для переключателей. Но это работает:

ColorStateList buttonStates = new ColorStateList(
        new int[][]{
                new int[]{-android.R.attr.state_enabled},
                new int[]{android.R.attr.state_checked},
                new int[]{}
        },
        new int[]{
                Color.BLUE,
                Color.RED,
                Color.GREEN
        }
);
switchInput.getThumbDrawable().setTintList(buttonStates);
switchInput.getTrackDrawable().setTintList(buttonStates);

Обновление для Android 6-7

Как сказал Херувим в комментариях, мы можем использовать новое, setThumbTintListи это сработало, как я ожидал. Мы также можем использовать setTrackTintList, но это применяет цвет как смесь, в результате чего в темных цветовых темах оно темнее, чем ожидалось, а в светлых темах светлее, чем ожидалось, иногда до такой степени, что оно становится невидимым. В Android 7 мне удалось минимизировать это изменение, переопределив режим оттенка дорожки , но я не смог получить приличные результаты из этого в Android 6. Возможно, вам потребуется определить дополнительные цвета, которые компенсируют смешивание. (У вас когда-нибудь возникало ощущение, что Google не хочет, чтобы мы настраивали внешний вид наших приложений?)

ColorStateList thumbStates = new ColorStateList(
        new int[][]{
                new int[]{-android.R.attr.state_enabled},
                new int[]{android.R.attr.state_checked},
                new int[]{}
        },
        new int[]{
                Color.BLUE,
                Color.RED,
                Color.GREEN
        }
);
switchInput.setThumbTintList(thumbStates);
if (Build.VERSION.SDK_INT >= 24) {
    ColorStateList trackStates = new ColorStateList(
            new int[][]{
                    new int[]{-android.R.attr.state_enabled},
                    new int[]{}
            },
            new int[]{
                    Color.GRAY,
                    Color.LTGRAY
            }
    );
    switchInput.setTrackTintList(trackStates);
    switchInput.setTrackTintMode(PorterDuff.Mode.OVERLAY);
}

Я использую подход getThumbDrawable / getTrackDrawable для создания переключателя, в котором оба состояния имеют одинаковый цвет - другими словами, переключатель не включает и не отключает что-то, а используется для выбора между двумя альтернативами.
— Natix

4
Получил, что DrawableCompat.setTintList позволит ему работать на предыдущих устройствах. Я вызываю: DrawableCompat.setTintList (switchCompat.getThumbDrawable (), foregroundState);
— Алексей

Пожалуйста, отредактируйте ответ, чтобы включить решение DrawableCompat. Работает отлично!
— Дмитрий Каратаев

API 23+: switchInput.setThumbTintList(buttonStates); работает и для Nougat. API 21-22: используйте DrawableCompat в соответствии с рекомендациями @Alexey. Он switchInput.setButtonTintList(buttonStates);не работал для меня, он не окрашивал состояния для моего Switch. API ниже 21: switchInput.getThumbDrawable().setColorFilter(someColor, PorterDuff.Mode.SrcIn); это сработало для меня. Я также работал с Xamarin, поэтому, если вы используете Xamarin.Forms, переведите их в C # в средствах визуализации Android.
— Херувим

37

Чтобы изменить стиль Switch без использования style.xml или Java-кода, вы можете настроить переход на макет XML:

<Switch
        android:id="@+id/checkbox"
        android:layout_width="wrap_content"
        android:thumbTint="@color/blue"
        android:trackTint="@color/white"
        android:checked="true"
        android:layout_height="wrap_content" />

Это атрибут android: thumbTint и android: trackTint, который позволил вам настроить цвет

Это визуальный результат для этого XML:

введите описание изображения здесь


17
Это меняет цвет большого пальца, независимо от того, включен он или нет.
— Android-разработчик

1
«Атрибут thumbTint используется только в API уровня 21 и выше»
— norbDEV

6
@norbDEV использует app: thumbTint и app: trackTint с SwitchCompat из библиотеки AppCompat.v7 для более низкого уровня API.
— Дэвид Дариас

Это работает, но что если вы хотите изменить цвет большого пальца, в зависимости от того, включен он или нет?
— TavernSenses

2
Если вы хотите использовать thumbTint ниже 21 использование app:thumbTintвместо android:thumbTintи изменения switchсSwitchCompat
— Kavita_p

33

Создайте пользовательский переключатель и переопределите setChecked для изменения цвета:

  public class SwitchPlus extends Switch {

    public SwitchPlus(Context context) {
        super(context);
    }

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

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

    @Override
    public void setChecked(boolean checked) {
        super.setChecked(checked);
        changeColor(checked);
    }

    private void changeColor(boolean isChecked) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
            int thumbColor;
            int trackColor;

            if(isChecked) {
                thumbColor = Color.argb(255, 253, 153, 0);
                trackColor = thumbColor;
            } else {
                thumbColor = Color.argb(255, 236, 236, 236);
                trackColor = Color.argb(255, 0, 0, 0);
            }

            try {
                getThumbDrawable().setColorFilter(thumbColor, PorterDuff.Mode.MULTIPLY);
                getTrackDrawable().setColorFilter(trackColor, PorterDuff.Mode.MULTIPLY);
            }
            catch (NullPointerException e) {
                e.printStackTrace();
            }
        }
    }
}

2
Первый пост, который на самом деле помог мне добиться индивидуального цвета для переключения материалов без использования стиля или тем. Спасибо !
— Мацкович

1
Ницца. У меня уже был свой настроенный Switch, поэтому мне пришлось только переопределить метод setChecked, и все они автоматически изменили свои цвета. Спасибо из Испании.
— Хулио

23
<androidx.appcompat.widget.SwitchCompat
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                app:thumbTint="@color/white"
                app:trackTint="@drawable/checker_track"/>

И внутри checker_track.xml:

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:color="@color/lightish_blue" android:state_checked="true"/>
    <item android:color="@color/hint" android:state_checked="false"/>
</selector>

thumbTintприменяется только на Android API 21 и выше. Как, если я хочу изменить цвет ниже Android 21?
— Джованка Бизано

developer.android.com/reference/android/support/v7/widget/… SwitchCompat обратно совместим с API 7 и выше
— wingear

1
Это 2020 год. Мне действительно интересно, где в мире люди все еще используют Android 21 и ниже?
— Зеешан

22

Хотя ответ SubChord является правильным, он на самом деле не отвечает на вопрос о том, как установить цвет «on», не затрагивая также другие виджеты. Чтобы сделать это, используйте ThemeOverlayв styles.xml:

<style name="ToggleSwitchTheme" parent="ThemeOverlay.AppCompat.Light">
    <item name="colorAccent">@color/green_bright</item>
</style>

И сослаться на это в вашем переключателе:

<android.support.v7.widget.SwitchCompat
  android:theme="@style/ToggleSwitchTheme" ... />

При этом он влияет ТОЛЬКО на цвет представлений, к которым вы хотите его применить.


По какой-то причине мне также пришлось установить «colorControlActivation» на то же значение, но для POC этого было достаточно, чтобы использовать «colorAccent». Как придешь?
— Android-разработчик

18

Я решил это, обновив Цветовой фильтр, когда состояние переключателя изменилось ...

public void bind(DetailItem item) {
    switchColor(item.toggle);
    listSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
                switchColor(b);
        }
    });
}

private void switchColor(boolean checked) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
        listSwitch.getThumbDrawable().setColorFilter(checked ? Color.BLACK : Color.WHITE, PorterDuff.Mode.MULTIPLY);
        listSwitch.getTrackDrawable().setColorFilter(!checked ? Color.BLACK : Color.WHITE, PorterDuff.Mode.MULTIPLY);
    }
}

13

Может быть, уже немного поздно, но для кнопок переключения кнопка toogle не является ответом, вы должны изменить drawable в параметре xml переключателя:

 android:thumb="your drawable here"

9

сделать drawable "newthumb.xml"

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:color="@color/Green" android:state_checked="true"/>
    <item android:color="@color/Red" android:state_checked="false"/>
</selector>

и сделать рисование "newtrack.xml"

<selector xmlns:android="http://schemas.android.com/apk/res/android">
        <item android:color="@color/black" android:state_checked="true"/>
        <item android:color="@color/white" android:state_checked="false"/>
    </selector>

и добавьте его в Switch:

<Switch
        android:trackTint="@drawable/newtrack"
        android:thumbTint="@drawable/newthumb"
         />

1
Это работает. Однако следует отметить, что AndroidStudio не сможет предложить ресурсы @drawable для trackTintили thumbTint. Нужно написать это вручную, и это работает.
— Бенджамин Басмачи

По какой-то причине это единственный ответ, который надежно работает на моем Huawei. Спасибо!
— einUsername

7

В Android Lollipop и выше определите его в стиле вашей темы:

<style name="BaseAppTheme" parent="Material.Theme">
    ...
    <item name="android:colorControlActivated">@color/color_switch</item>
</style>

Проблема с этим решением состоит в том, что оно также меняет цвета моих выбранных текстовых сообщений, что не то, что я хочу.
— кодингинг

@ Codewing Конечно, будет. Потому что это установлено в глобальных предпочтениях стиля. Чтобы достичь своей цели, нужно найти идентификатор представления целевого вида и изменить его атрибуты.
— emen

ОК, это для позиции «Вкл». Как насчет изменения цвета большого пальца для положения «Выкл»?
— TavernSenses

7

Создайте свое собственное изображение из 9 патчей и установите его в качестве фона кнопки переключения.

http://radleymarx.com/2011/simple-guide-to-9-patch/


2
Да, мог бы сделать это, но наверняка должен быть более простой способ? Селекторы может быть?
— JamesSugrue

Нет, проще нет. Вы не можете волшебным образом изменить цвет изображения :)
— you786

Хорошая точка зрения. Я не до конца понял, как это работает, пока не посмотрел глубже.
— JamesSugrue

@Denizen, ты уверен? Если так, напишите ответ, и я проголосую.
— you786

@Denizen Пожалуйста, удалите свой комментарий. Android Switch всегда возвращает null для getBackground (), я потратил 30 минут, пытаясь это сделать.
— Шириш Хервейд

5

Решение, предложенное Arlomedia, сработало для меня. По поводу его вопроса о лишнем пространстве я решил убрать все прокладки с переключателя.

РЕДАКТИРОВАТЬ

Как и просил, вот что у меня есть.

В файле макета мой переключатель находится внутри линейного макета и после TextView.

<LinearLayout
        android:id="@+id/myLinearLayout"
        android:orientation="horizontal"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:layout_gravity="center_horizontal|center"
        android:gravity="right"
        android:padding="10dp"
        android:layout_marginTop="0dp"
        android:background="@drawable/bkg_myLinearLayout"
        android:layout_marginBottom="0dp">
        <TextView
            android:id="@+id/myTextForTheSwitch"
            android:layout_height="wrap_content"
            android:text="@string/TextForTheSwitch"
            android:textSize="18sp"
            android:layout_centerHorizontal="true"
            android:layout_gravity="center_horizontal|center"
            android:gravity="right"
            android:layout_width="wrap_content"
            android:paddingRight="20dp"
            android:textColor="@color/text_white" />
        <Switch
            android:id="@+id/mySwitch"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textOn="@string/On"
            android:textOff="@string/Off"
            android:layout_centerHorizontal="true"
            android:layout_gravity="center_horizontal"
            android:layout_toRightOf="@id/myTextForTheSwitch"
            android:layout_alignBaseline="@id/myTextForTheSwitch"
            android:gravity="right" />
    </LinearLayout>

Так как я работаю с Xamarin / Monodroid (мин. Android 4.1), мой код:

Android.Graphics.Color colorOn = Android.Graphics.Color.Green;
Android.Graphics.Color colorOff = Android.Graphics.Color.Gray;
Android.Graphics.Color colorDisabled = Android.Graphics.Color.Green;

StateListDrawable drawable = new StateListDrawable();
drawable.AddState(new int[] { Android.Resource.Attribute.StateChecked }, new ColorDrawable(colorOn));
drawable.AddState(new int[] { -Android.Resource.Attribute.StateEnabled }, new ColorDrawable(colorDisabled));
drawable.AddState(new int[] { }, new ColorDrawable(colorOff));

swtch_EnableEdit.ThumbDrawable = drawable;

swtch_EnableEdit предварительно определен так (Xamarin):

Switch swtch_EnableEdit = view.FindViewById<Switch>(Resource.Id.mySwitch);

Я вообще не устанавливаю отступы и не вызываю .setPadding (0, 0, 0, 0).


Можете ли вы предоставить код для этого? Я попытался switchInput.setPadding (0, 0, 0, 0), но ничего не изменилось.
— arlomedia

1
Протестировано в Xamarin с использованием библиотеки AppCompat для таргетинга 5.x, и это сработало, как рекламировалось.
— Alex.Ritna

4

Вы можете сделать собственный стиль для переключателя виджета, который использует цветовой акцент в качестве значения по умолчанию, когда вы делаете собственный стиль для него

<style name="switchStyle" parent="Theme.AppCompat.Light">
    <item name="colorPrimary">@color/colorPrimary</item>
    <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
    <item name="colorAccent">@color/colorPrimary</item>    <!-- set your color -->
</style>    


1

Попробуйте найти правильный ответ здесь: Селектор на цвет фона TextView . В двух словах вы должны создать Shape в XML с цветом, а затем присвоить ему состояние «флажок» в вашем селекторе.


Хорошее решение, но знаете ли вы, как мы можем динамически менять цвет?
— inverted_index

Вам просто нужно установить переключатель в качестве фонового ресурса
— Shamm

1

Я не знаю, как это сделать из Java, но если у вас есть стиль, определенный для вашего приложения, вы можете добавить эту строку в свой стиль, и у вас будет нужный мне цвет, я использовал # 3F51B5

<color name="ascentColor">#3F51B5</color>

1

Самый простой способ - определить оттенок дорожки и установить режим оттенка src_over, чтобы убрать 30% прозрачности.

android:trackTint="@drawable/toggle_style"
android:trackTintMode="src_over"

toggle_style.xml

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:color="@color/informationDefault"
        android:state_checked="true"
        />
    <item android:color="@color/textDisabled" android:state_checked="false"/>
</selector>

0

В дополнение к существующим ответам: вы можете настроить большой палец и трек, используя селекторы в res/colorпапке, например:

switch_track_selector

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

switch_thumb_selector

<selector
    xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:color="@color/darkBlue"
        android:state_checked="true" />
    <item android:color="@color/white"/>
</selector>

Используйте эти селекторы для настройки оттенков дорожки и большого пальца:

<androidx.appcompat.widget.SwitchCompat
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    app:trackTint="@color/switch_track_selector"
    app:thumbTint="@color/switch_thumb_selector"/>

Имейте в виду , что если вы используете Standart Switchи androidпространство имен для этих атрибутов, он будет работать только для API 23 и позже, поэтому использование SwitchCompatс appпространством имен в xmlns:app="http://schemas.android.com/apk/res-auto"качестве универсального решения.

Результат:

введите описание изображения здесь


0

В XML вы можете изменить цвет как:

 <androidx.appcompat.widget.SwitchCompat
    android:id="@+id/notificationSwitch"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:checked="true"
    app:thumbTint="@color/darkBlue"
    app:trackTint="@color/colorGrey"/>

Динамически вы можете изменить как:

Switch.thumbDrawable.setColorFilter(ContextCompat.getColor(requireActivity(), R.color.darkBlue), PorterDuff.Mode.MULTIPLY)

-1

Решение для Android Studio 3.6:

yourSwitch.setTextColor(getResources().getColor(R.color.yourColor));

Изменяет цвет текста в определенном значении файла XML (yourColor).

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.