Как изменить цвет SwitchCompat из библиотеки AppCompat

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

В выпуске библиотеки AppCompat v21 появился новый элемент управления android.support.v7.widget.SwitchCompat.

Можно ли программно изменить цвет SwitchCompat без селектора, который можно рисовать, но с помощью XML или кода?

Ответ 1

Атрибут AppCompat тонировка:

Во-первых, вам нужно взглянуть на статью appCompat lib там и на различные атрибуты, которые вы можете установить:

colorPrimary: основной фирменный цвет для приложения. По умолчанию этот цвет применяется к фону панели действий.

colorPrimaryDark: темный вариант основного фирменного цвета. По умолчанию это цвет, применяемый к строке состояния (с помощью statusBarColor) и панели навигации (с помощью navigationBarColor).

colorAccent: яркое дополнение к основной цветовой гамме. По умолчанию этот цвет применяется к элементам управления каркасом (с помощью colorControlActivation).

colorControlNormal: цвет, применяемый к элементам управления каркаса в их нормальном состоянии.

colorControlActivation: цвет, применяемый к элементам управления каркаса в их активированном состоянии (например, проверено, включено).

colorControlHighlight: цвет, применяемый к подсветке элемента управления каркасом (например, рябь, селекторы списка).

colorButtonNormal: цвет, применяемый к кнопкам рамки в их нормальном состоянии.

colorSwitchThumbNormal: цвет, применяемый к каркасу, переключает большие пальцы в их обычное состояние. (выключить)


Если все пользовательские параметры одинаковы в одном действии:

С помощью предыдущих атрибутов вы можете определить собственную тему для каждого действия:

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

и:

<manifest>
...
    <activity
        android:name=".MainActivity" 
        android:theme="@style/Theme.MyActivityTheme">
    </activity>
...
</manifest>

Если вы хотите использовать разные пользовательские переключатели в одном действии:

Так как тонирование виджета в appcompat работает, перехватывая любой разметку макета и вставляя на его место специальную версию виджета с учетом оттенков (см. статью Криса Банеса об этом), вы не можете применять собственный стиль к каждому переключателю Ваш макет XML файла. Вы должны установить пользовательский контекст, который будет переключаться с правильными цветами.

-

Для этого для pre-5.0 вам нужно создать контекст, который накладывает глобальную тему на таможенные атрибуты, а затем программно создать переключатели:

ContextThemeWrapper ctw = ContextThemeWrapper(getActivity(), R.style.Color1SwitchStyle); 
SwitchCompat sc = new SwitchCompat(ctw)

Начиная с AppCompat v22.1, вы можете использовать следующий XML для применения темы к виджету переключения:

<RelativeLayout
    xmlns:app="http://schemas.android.com/apk/res-auto"
    ...>

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

Ваша тема переключателя:

<style name="Color1SwitchStyle">
    <item name="colorControlActivated">@color/my_awesome_color</item>
</style>

-

В Android 5.0 это выглядит так, как будто новый вид атрибута оживает: android:theme (аналогично одному использованию для объявления активности в манифесте). Основываясь на другом посте Криса Банеса post, с последним вы сможете определить собственную тему непосредственно в представлении из вашего макета XML:

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

Чтобы изменить цвет дорожки SwitchCompat

Благодаря vine'th я дополняю свой ответ ссылкой на SO-ответ, в котором объясняется, как указать передний план трека, когда переключатель выключен, он там.

Ответ 2

Хорошо, так что извините, но большинство из этих ответов неполны или имеют небольшую ошибку. Очень полный ответ от @austyn-mahoney является правильным и источником для этого ответа, но он сложный, и вы, вероятно, просто хотите настроить переключатель. Элементы управления Styling в разных версиях Android - это эпическая боль в заднице. Вытащив мои волосы в течение нескольких дней на проект с очень жесткими ограничениями конструкции, я, наконец, сломался и написал тестовое приложение, а затем действительно выкопал и протестировал различные решения там для стилейных переключателей и флажков, поскольку, когда у дизайна есть один он часто имеет другой. Вот что я нашел...

Во-первых: Вы не можете начертить ни один из них, но вы можете применить тему для всех из них или только один из них.

Второе:. Вы можете сделать все это из XML, и вам не нужны другие значения-v21/styles.xml.

В-третьих:, когда дело доходит до коммутаторов, у вас есть два основных варианта, если вы хотите поддерживать более старые версии Android (например, я уверен, что вы это делаете)...

  • Вы можете использовать SwitchCompat, и вы сможете сделать его похожим на разных платформах.
  • Вы можете использовать Switch, и вы сможете обсуждать его с остальной частью темы, или только с этим конкретным коммутатором, и на более старых версиях Android вы просто увидите нерасширенный старый квадратный переключатель.

Хорошо теперь для простого ссылочного кода. Опять же, если вы создадите простой Hello World! и отбросьте этот код, вы можете играть в своем сердце. Все это плита котла здесь, поэтому я просто собираюсь включить XML для активности и стиля...

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>

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

API_21:

API 21

API_18:

API18

Ответ 3

Я думаю, что ответ в ссылке ниже лучше

Как изменить цвет трека 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>

Ответ 4

Поэтому в некоторые дни мне не хватает клеток мозга и:

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

не применяется тема, потому что стиль неправильный. Я должен был использовать приложение: theme: P

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

Whoopsies. Этот пост был тем, что дало мне понять мою ошибку... надеюсь, если кто-то споткнутся об этом, это поможет им, как это сделал я. Спасибо Гаэтан Маиссе за ваш ответ

Ответ 5

Будьте в курсе ошибок с помощью SwitchCompat

Это ошибка с поврежденным файлом в drawable-hdpi на AppCompat https://code.google.com/p/android/issues/detail?id=78262

Чтобы исправить это, juste переопределит его этими 2 файлами https://github.com/lopespm/quick-fix-switchcompat-resources Добавьте его в свой каталог 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"
/>

И ничего не было нужно на Java

Ответ 6

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

в style.xml

<style name="Custom.Widget.SwitchCompat" parent="Widget.AppCompat.CompoundButton.Switch" >
            <item name="android:textColorPrimary">@color/blue</item>  <!--textColor on activated state -->
      </style>

Ответ 7

Чтобы иметь больший контроль над цветом дорожки (нет API управляемых альфа-изменений), я расширил SwitchCompat и программно стилю элементов:

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

Всякий раз, когда я хочу использовать CustomizedSwitch, я просто добавляю его в файл xml.

Ответ 8

Мой рабочий пример использования стиля и android: theme одновременно (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>

Ответ 9

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

Стиль

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

Цвета

enter image description here

раскладка

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

Результат

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

enter image description here

источник

Ответ 10

Просто

 android:buttonTint="@color/primary"