Змініть колір "включення" перемикача


156

Я використовую стандартне управління Switch з темою holo.light у програмі ICS.

Я хочу змінити виділений або на стан стану кнопки Toggle із стандартного світло-синього на зелений.

Це повинно бути легко, але я не можу зрозуміти, як це зробити.


Я насправді не бачу іншого способу, крім копіювання відповідних ресурсів платформи (файли селектора та * .png) та зміни стану "on", який можна малювати. Не забудьте Switchзгодом вказати на цей спеціальний селектор.
МЗ.

Відповіді:


100

На сьогодні краще використовувати 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
'on' є colorAccent, 'off' є colorSwitchThumbNormal. Якщо ви використовуєте AppCompatтему, вам потрібно SwitchCompatскоріше використовувати Switch. Якщо ви використовуєте SDK 23+, ви можете використовувати android:thumbTintта android:thumbTintModeз ColorStateList.
Том

1
@Tom plz відповість, що ці "android: thumbTint" речі працюватимуть на пристроях <23
Shirish Herwade

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
Добре, за винятком colorControlActivate - він не встановлює колір доріжки, а лише великий палець.
Покажчик Нуль

1
тут рішення для комутатора і SwitchCompat: stackoverflow.com/a/47036089/5869630
roghayeh Хоссейні

Теги <style>, необхідні для запису в розділі res >> values ​​>> styles.xml та на XML-сторінці для <Switch ...>, слід додати лише рядок під назвою: android: topic = "@ style / SCBSwitch і мої кольори : colorControlActivate "> # ff0000 and colorSwitchThumbNormal"> # 00ff00 та android: colorForeground "> # 00ff00
Бей

@OviTrif Чудовий! Вражає, як важко знайти просту подібну інформацію. Багато і багато відповідей, які я читав, і ніхто досі не давав робочої відповіді. Нарешті!
jairhumber до

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);
}

Я використовую підхід getThumbDravable / getTrackDravable, щоб створити комутатор, коли обидва стану мають один і той же колір - іншими словами, комутатор щось не вмикає / відключає, але використовується для вибору між двома альтернативами.
Natix

4
Зрозуміло, що DravableCompat.setTintList дозволить йому працювати на попередніх пристроях. Я закликаю: DravableCompat.setTintList (switchCompat.getThumbDravable (), foregroundState);
Олексій

Відредагуйте відповідь, щоб включити рішення DravableCompat. Це прекрасно працює!
Дмитро Каратаєв

API 23+: switchInput.setThumbTintList(buttonStates); працює і для Nougat. API 21-22: Використовуйте DravableCompat, як запропонував @Alexey. Він switchInput.setButtonTintList(buttonStates);не працював для мене, він не забарвлював стани мого Switch. API нижче 21: switchInput.getThumbDrawable().setColorFilter(someColor, PorterDuff.Mode.SrcIn); Це працювало для мене. Я працював і з Xamarin, тому перекладіть їх на C # в Android-рендері, якщо ви використовуєте Xamarin.Forms.
Черубі

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
Це змінює колір великого пальця, незалежно від того, увімкнено чи вимкнено він.
андроїд розробник

1
"Attribute thumbTint використовується лише в API рівня 21 і вище"
norbDEV

6
@norbDEV використовувати додаток: thumbTint та додаток: trackTint за допомогою SwitchCompat з бібліотеки AppCompat.v7 для нижчого рівня API.
Девід Даріас

Це працює, але що робити, якщо ви хочете змінити колір для великого пальця, залежно від того, увімкнено він чи вимкнено?
TavernSenses

2
Якщо ви хочете використовувати thumbTint нижче 21 використання app:thumbTintзамість android:thumbTintі зміни switchзSwitchCompat
Kavita_p

33

Створіть користувацький перемикач та замініть набірПеревірено, щоб змінити колір:

  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
Приємно. У мене вже був власний індивідуальний перемикач, тому мені довелося лише перекрити метод setChecked, і всі вони автоматично змінили свої кольори. Спасибі від Іспанії.
Хуліо

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

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


З якоїсь причини мені також довелося встановити "colorControlActivate" на те саме значення, але на POC цього було достатньо використовувати "colorAccent". Як це?
андроїд розробник

22
<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 і нижче?
zeeshan

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 не є відповіддю, ви повинні змінити параметр xml у перемикачі:

 android:thumb="your drawable here"

9

зробити мальованим "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 Звичайно, так і буде. Тому що це встановлено у світовій стилістиці. Щоб досягти своєї мети, потрібно знайти ідентифікатор подання цільового перегляду та змінити його атрибути.
емен

Гаразд, це для позиції "Увімкнено". Як щодо зміни кольору великого пальця для положення «Вимкнено»?
TavernSenses

7

Створіть власне 9-латне зображення та встановіть його як фон кнопки перемикання.

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


2
Так, міг би це зробити, але, звичайно, ОБОВ'ЯЗКОВО бути простішим способом? Можливо, селектори?
JamesSugrue

Ні, немає простішого шляху. Ви не можете чарівно змінити колір зображення :)
you786

Гарна думка. Я не до кінця зрозумів, як це працює, поки не заглянув глибше.
JamesSugrue

@Denizen, ти впевнений? Якщо так, опублікуйте відповідь, і я проголосую за неї.
you786

@Denizen Видаліть ваш коментар. Android Switch завжди повертає нуль для getBackground (), я витрачав це 30 хвилин, намагаючись це зробити.
Shirish Herwade

5

Рішення, запропоноване арломедією, працювало для мене. Про свою проблему з додатковим простором я вирішив видалити всі накладки на комутатор.

EDIT

За запитом, ось що у мене є.

У файлі компонування мій перемикач знаходиться всередині лінійного макета та після 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

Вам просто потрібно встановити селектор як фоновий ресурс
Шамм

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

Майте на увазі, що якщо ви використовуєте стандарт 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.