web-dev-qa-db-ja.com

AppCompatライブラリからSwitchCompatの色を変更する方法

私のアプリケーションには異なる色のスイッチコントロールがいくつかあり、それらの色を変更するために、複数のカスタム描画可能なセレクターを使用しました。

新しいAndroid.support.v7.widget.SwitchCompatコントロールがAppCompat v21ライブラリのリリースで導入されました。

顧客が描画可能なセレクタを使用せずに、XMLまたはコードを使用してSwitchCompatの色をプログラムで変更することは可能ですか?

117
Orest

AppCompat着色属性:

最初に、appCompat libの記事 there と、設定できるさまざまな属性を確認する必要があります。

colorPrimary:アプリの主要なブランド色。デフォルトでは、これはアクションバーの背景に適用される色です。

colorPrimaryDark:プライマリブランディングカラーのダークバリアント。デフォルトでは、これはステータスバー(statusBarColor経由)およびナビゲーションバー(navigationBarColor経由)に適用される色です。

colorAccent:主要なブランド色を明るく引き立たせます。デフォルトでは、これはフレームワークコントロールに適用される色です(colorControlActivatedを介して)。

colorControlNormal:通常の状態のフレームワークコントロールに適用される色。

colorControlActivated:フレームワークコントロールのアクティブ化(チェック済み、スイッチオンなど)状態に適用される色。

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でのウィジェットの色付けは、レイアウトインフレーションをインターセプトし、その場所に特別な色合いを認識したバージョンのウィジェットを挿入することで機能するため(Chris Banes post about it を参照)、各スイッチにカスタムスタイルを適用することはできませんレイアウト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(マニフェストでのアクティビティ宣言の1つの使用と同じ)が新しいビュー属性が生き返ったように見えます。別のChris Banes 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回答へのリンクで回答を完了します。これは there です。

311
Gaëtan M.

わかりました。すみませんが、これらの回答のほとんどは不完全であるか、いくつかのマイナーなバグがあります。 @ austyn-mahoneyからの非常に完全な回答は正確であり、この回答のソースですが、それは複雑であり、おそらくスイッチをスタイルするだけです。 Androidの異なるバージョン間での「スタイリング」コントロールは、お尻にepicの痛みです。設計上の制約が非常に厳しいプロジェクトで何日間も髪を引っ張った後、最終的に故障してテストアプリを作成し、スイッチとチェックボックスのスタイリングに関するさまざまなソリューションを実際に掘り下げてテストしました。頻繁にもう一方があります。ここに私が見つけたものがあります...

最初:実際にそれらのいずれかをスタイルすることはできませんが、それらのすべてまたは1つだけにテーマを適用できます。

Second:XMLからすべてを行うことができ、2番目のvalue-v21/styles.xmlは必要ありません。

第3:スイッチに関しては、古いバージョンのAndroidをサポートしたい場合、2つの基本的な選択肢があります(きっとそうです)。 。

  1. SwitchCompatを使用すると、プラットフォーム間で同じように表示できます。
  2. 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

55
Aaron Cooley

下のリンクの答えが良いと思います

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

それで、数日、私は脳細胞を欠き、そして:

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

スタイルが正しくないため、テーマは適用されません。 app:theme:Pを使用することになっていた

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

おっと。この投稿は、私の間違いについての洞察を私に与えてくれたものです...誰かがこれに出くわしたなら、それが私のように助けてくれることを願っています。答えてくれてありがとう

5
isuPatches

SwitchCompatの既知のバグに注意する

AppCompatのdrawable-hdpiのファイルが破損しているバグです https://code.google.com/p/Android/issues/detail?id=78262

修正するには、この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では何も必要ありませんでした

2
Anthone
<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>
1
NickUnuchek

トラックの色をより細かく制御するために(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ファイルに1つ追加するだけです。

1
Tom Howard

ただ

 Android:buttonTint="@color/primary"
0
Pablo Cegarra

スタイルと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>
0
Andrew Glukhoff