異なる色の標準のAndroidボタン


735

クライアントのブランドに合わせるために、標準のAndroidボタンの色を少し変更したいと思います。

これまでにこれを行うことがわかった最良の方法は、Buttonのドローアブルをにあるドローアブルに変更することですres/drawable/red_button.xml

<?xml version="1.0" encoding="utf-8"?>    
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="true" android:drawable="@drawable/red_button_pressed" />
    <item android:state_focused="true" android:drawable="@drawable/red_button_focus" />
    <item android:drawable="@drawable/red_button_rest" />
</selector>

ただし、そのためには、カスタマイズするボタンごとに3つの異なるドローアブルを実際に作成する必要があります(1つは休止中のボタン用、もう1つはフォーカスされたとき、もう1つは押されたとき)。それは私が必要とするよりも複雑で、非乾燥です。

私が本当にやりたいのは、ボタンにある種の色変換を適用することだけです。ボタンの色を変更するよりも簡単な方法はありますか?


回答:


724

これはすべて1つのファイルでかなり簡単に実行できることを発見しました。という名前のファイルに次のコードのようなものを置き、ボタンビューにcustom_button.xml設定background="@drawable/custom_button"します。

<?xml version="1.0" encoding="utf-8"?>
<selector
    xmlns:android="http://schemas.android.com/apk/res/android">

    <item android:state_pressed="true" >
        <shape>
            <gradient
                android:startColor="@color/yellow1"
                android:endColor="@color/yellow2"
                android:angle="270" />
            <stroke
                android:width="3dp"
                android:color="@color/grey05" />
            <corners
                android:radius="3dp" />
            <padding
                android:left="10dp"
                android:top="10dp"
                android:right="10dp"
                android:bottom="10dp" />
        </shape>
    </item>

    <item android:state_focused="true" >
        <shape>
            <gradient
                android:endColor="@color/orange4"
                android:startColor="@color/orange5"
                android:angle="270" />
            <stroke
                android:width="3dp"
                android:color="@color/grey05" />
            <corners
                android:radius="3dp" />
            <padding
                android:left="10dp"
                android:top="10dp"
                android:right="10dp"
                android:bottom="10dp" />
        </shape>
    </item>

    <item>        
        <shape>
            <gradient
                android:endColor="@color/blue2"
                android:startColor="@color/blue25"
                android:angle="270" />
            <stroke
                android:width="3dp"
                android:color="@color/grey05" />
            <corners
                android:radius="3dp" />
            <padding
                android:left="10dp"
                android:top="10dp"
                android:right="10dp"
                android:bottom="10dp" />
        </shape>
    </item>
</selector>

43
これは背景色に適しています。テキストの色を同じ方法で設定できますか?
レイチェル

8
これは私に"Error: No resource found that matches the given name (at 'color' with value '@color/yellow1')" これらの組み込み色への参照がありますか?これを機能させるにはres / values / color.xmlが必要なようです
Harry Wood

8
@HarryWoodでは、res / values / colors.xmlでこれらの色を定義する必要があります。または、テスト目的で、それらを「#ff0000」、「#00ff00」に置き換えます。@ cfarm54そのファイルは、res / drawable / custom_button.xmlフォルダーに配置されます。@emmbyコードスニペットありがとうございます。
espinchi

17
ありがとうございます。また、これを試す他の人々のために、セレクター内のアイテムの順序は重要です。状態フィルターなしで<item>をファイルの最初に置くと、それが残りを上書きします。
mikerowehl、2011

9
あなたのres /「描画可能」フォルダ内のこの作品、入れcustom_button.xmlを作るために-そしてこれらのコンテンツを持つファイルのres /値/ colors.xml作成:stackoverflow.com/questions/3738886/... -のいずれかのファイルに色の名前を変更します機能させるには
sami

308

Tomaszの回答に続いて、PorterDuff乗算モードを使用して、ボタン全体のシェードをプログラムで設定することもできます。これにより、色合いだけでなくボタンの色も変更されます。

標準の灰色のボタンで始めた場合:

button.getBackground().setColorFilter(0xFFFF0000, PorterDuff.Mode.MULTIPLY);

赤い網掛けのボタンが表示されます

button.getBackground().setColorFilter(0xFF00FF00, PorterDuff.Mode.MULTIPLY);

緑の網掛けのボタンなどが表示されます。最初の値は16進形式の色です。

現在のボタンのカラー値にカラー値を乗算することで機能します。これらのモードでできることは他にもたくさんあると思います。


2
うわー、ちょうどそれを試してみました、それは完全に素晴らしいです。ありがとうございました!どういうわけかxmlでそれを達成する方法があるかどうか知っていますか?
emmby 2010

4
皆さん、HTC Desireでチェックしてください!異なる標準ボタンがあります。このコードを使用する私のボタンは、「40dp」のような特定のlayout_widthを設定すると、そこにすごく見えます。「wrap_content」では問題ありません。
OneWorld、2010

5
確認済み、このソリューションはHTC Sense UIではうまく機能しません
emmby

19
Eclipseは可能修正としてこれを表示されません:import android.graphics.PorterDuff;
誰かのどこか

2
誰かがこれがICSで機能しないことで何か問題がありましたか?それは...私のためにエミュレータまたは電話で動作するようには思えない
Stev_k

149

マイク、あなたはカラーフィルターに興味があるかもしれません。

例:

button.getBackground().setColorFilter(new LightingColorFilter(0xFFFFFFFF, 0xFFAA0000));

これを試して、希望の色を実現してください。


setColorFilterメソッドでnullを渡してみてください。試したことはありませんが、うまくいくはずです。
Tomasz

6
設定を解除する@Pacerier:button.getBackground()。clearColorFilter();
Stan Kurdziel 2012年

3
Colorクラスを使用して色を選択することをお勧めします:developer.android.com/reference/android/graphics/Color.html
Mugen

暗いテーマに最適!私は、他の上位の回答(setColorFilter(0xFFFF0000、PorterDuff.Mode.MULTIPLY))がライトテーマに適していると思います。
java.is.for.desktop '13 / 09/13

85

これは、API 15から完全に機能する私のソリューションです。このソリューションは、マテリアルなどのすべてのデフォルトボタンクリック効果を保持しますRippleEffect。下位のAPIではテストしていませんが、動作するはずです。

あなたがする必要があるのは、

1)のみ変更するスタイルを作成しますcolorAccent

<style name="Facebook.Button" parent="ThemeOverlay.AppCompat">
    <item name="colorAccent">@color/com_facebook_blue</item>
</style>

残りのスタイルを維持するために、ThemeOverlay.AppCompatまたはメインAppThemeを親として使用することをお勧めします。

2)buttonウィジェットに次の2行を追加します。

style="@style/Widget.AppCompat.Button.Colored"
android:theme="@style/Facebook.Button"

新しいものcolorAccentがAndroid Studioプレビューに表示されないことがありますが、スマートフォンでアプリを起動すると、色が変更されます。


サンプルボタンウィジェット

<Button
    android:id="@+id/sign_in_with_facebook"
    style="@style/Widget.AppCompat.Button.Colored"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    android:text="@string/sign_in_facebook"
    android:textColor="@android:color/white"
    android:theme="@style/Facebook.Button" />

カスタムカラーのサンプルボタン


1
この行は何をしますか?"style =" @ style / Widget.AppCompat.Button.Colored ""
Charles Li

2
これは、スタイルとテーマの違いを理解するのに役立ちました。ありがとうございました。
rpattabi 2017年

2
受け入れられた答えは正しいですが古すぎます。これはシンプルで最新の答えです。
正宗白布鞋

この回答の問題は、その設定colorAccentがボタンの背景だけに影響を与えるわけではないということです。
Blcknx

@Blcknx例えば何ですか?
RediOne1 2018年

61

次の属性でappcompat-v7のAppCompatButtonを使用することもできbackgroundTintます。

<android.support.v7.widget.AppCompatButton
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:backgroundTint="#ffaa00"/>

4
「android:」名前空間を使用しても動作しませんでした。しかし、代わりに「app:」名前空間を使用したときに機能しました。
David Velasquez 2017

@DavidVelasquez android:Lollipopでも動作しましたが、android:名前空間は何も変更しませんでした。助けてくれてありがとう!
Avinash Prabhakar 2017

これが最も簡単な解決策であり、受け入れられる答えになるはずです。android:backgroundTintを使用するとうまくいきます。
Ramashish Baranwal

1
AppCompatを使用する場合のapp:backgroundTint代わりにandroid:backgroundTintする必要があります。
Hafez Divandari

23

@conjugatedirectionと@Tomaszの以前の回答にあるカラーフィルターの提案が気に入っています。しかし、これまでに提供されたコードは、思ったほど簡単には適用できないことがわかりました。

まず、カラーフィルターを適用してクリアする場所については触れられていません。これを行うには他にも良い場所がある可能性がありますが、私が思いついたのはOnTouchListenerでした

元の質問を読んだところ、理想的な解決策は画像を含まないものになるでしょう。@emmbyからのcustom_button.xmlを使用して受け入れられた回答は、それがあなたの目標である場合、おそらくカラーフィルターよりも適しています。私の場合、UIデザイナーからのpng画像から始めて、ボタンの外観を想定しています。ボタンの背景をこの画像に設定すると、デフォルトのハイライトフィードバックが完全に失われます。このコードは、その動作をプログラムによる暗くする効果に置き換えます。

button.setOnTouchListener(new OnTouchListener() {
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                // 0x6D6D6D sets how much to darken - tweak as desired
                setColorFilter(v, 0x6D6D6D);
                break;
            // remove the filter when moving off the button
            // the same way a selector implementation would 
            case MotionEvent.ACTION_MOVE:
                Rect r = new Rect();
                v.getLocalVisibleRect(r);
                if (!r.contains((int) event.getX(), (int) event.getY())) {
                    setColorFilter(v, null);
                }
                break;
            case MotionEvent.ACTION_OUTSIDE:
            case MotionEvent.ACTION_CANCEL:
            case MotionEvent.ACTION_UP:
                setColorFilter(v, null);
                break;
        }
        return false;
    }

    private void setColorFilter(View v, Integer filter) {
        if (filter == null) v.getBackground().clearColorFilter();
        else {
            // To lighten instead of darken, try this:
            // LightingColorFilter lighten = new LightingColorFilter(0xFFFFFF, filter);
            LightingColorFilter darken = new LightingColorFilter(filter, 0x000000);
            v.getBackground().setColorFilter(darken);
        }
        // required on Android 2.3.7 for filter change to take effect (but not on 4.0.4)
        v.getBackground().invalidateSelf();
    }
});

私はこれを複数のボタンに適用するための個別のクラスとして抽出しました-アイデアを得るために匿名の内部クラスとして示されています。


それは素晴らしい解決策でした!デフォルトでiOSを使用する場合とほぼ同じ影響があり、これはデザイナーが好むものです:-)
Christer Nordvik

同じ画面で同じ背景の2つのボタンを使ってこれを試しましたが、効果はonTouchの両方のボタンに適用されます
Goofy

16

XMLでカラーボタンを作成する場合は、フォーカスされた状態と押された状態を別のファイルで指定して再利用することにより、コードを少し見やすくすることができます。私の緑色のボタンは次のようになります。

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <item android:state_focused="true" android:drawable="@drawable/button_focused"/>
    <item android:state_pressed="true" android:drawable="@drawable/button_pressed"/>

    <item>
        <shape>
            <gradient android:startColor="#ff00ff00" android:endColor="#bb00ff00" android:angle="270" />
            <stroke android:width="1dp" android:color="#bb00ff00" />
            <corners android:radius="3dp" />
            <padding android:left="10dp" android:top="10dp" android:right="10dp" android:bottom="10dp" />
        </shape>
    </item>

</selector>

1
いいね。どのようにしてフォーカスされた状態と押された状態をボタンの標準のAndroid定義に戻すことができますか?
larham1

標準のAndroidボタンは9パッチビットマップとして実装されているため、そうではないと思います。
ヘミッシュ2012年

12

すべてのAndroidバージョンで動作する最短のソリューション:

<Button
     app:backgroundTint="@color/my_color"

注意事項/要件

  • 使用しapp:た名前空間とないandroid:名前空間を!
  • appcompatバージョン> 24.2.0

    依存関係{コンパイル 'com.android.support:appcompat-v7:25.3.1'}

説明ここに画像の説明を入力してください


1
興味深いことに、私にとってapp:backgroundTint="@color/my_color"はうまくいきませんでした。android:backgroundTint="@color/my_color"でも完璧に機能しました。
イゴール

これは私にとって最も短くてクリーンなソリューションであり、それがすべてです。
マーティ

11

私はこのアプローチを使用しています

style.xml

<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
    <item name="android:colorPrimaryDark">#413152</item>
    <item name="android:colorPrimary">#534364</item>
    <item name="android:colorAccent">#534364</item>
    <item name="android:buttonStyle">@style/MyButtonStyle</item>
</style>

<style name="MyButtonStyle" parent="Widget.AppCompat.Button.Colored">
    <item name="android:colorButtonNormal">#534364</item>
    <item name="android:textColor">#ffffff</item>
</style>

上からわかるように、ボタンにはカスタムスタイルを使用しています。ボタンカラーはアクセントカラーに対応。android:backgroundGoogleが提供する波及効果を失わないため、これは設定よりもはるかに優れたアプローチです。


8

今よりずっと簡単な方法があります:android-holo-colors.com

すべてのホロドローアブル(ボタン、スピナーなど)の色を簡単に変更できます。色を選択してから、すべての解像度のドローアブルを含むzipファイルをダウンロードします。


8

次のように使用します。

buttonOBJ.getBackground().setColorFilter(Color.parseColor("#YOUR_HEX_COLOR_CODE"), PorterDuff.Mode.MULTIPLY);


3

DroidUXコンポーネントライブラリを持っているColorButtonあなたも、あなたのアプリがそれを許可する場合、ユーザーがボタンの色/テーマを設定してみましょうことができますので、その色のXML定義を経由し、プログラム実行時の両方、容易に変更できるウィジェットを。


3

このオンラインツールを 使用してボタンhttp://angrytools.com/android/button/android:background="@drawable/custom_btn"カスタマイズし、レイアウトでカスタマイズしたボタンを定義することもできます。


2

ボタンのテーマをこれに設定できます

<style name="AppTheme.ButtonBlue" parent="Widget.AppCompat.Button.Colored">
 <item name="colorButtonNormal">@color/HEXColor</item>
 <item name="android:textColor">@color/HEXColor</item>
</style>

1

簡単な方法は、半径、グラデーション、押された色、通常の色など、必要なすべてのプロパティを受け入れるカスタムボタンクラスを定義し、XMLを使用して背景を設定する代わりに、XMLレイアウトでそれを使用することです。サンプルはこちら

これは、半径や選択した色などの同じプロパティを持つボタンがたくさんある場合に非常に便利です。継承したボタンをカスタマイズして、これらの追加のプロパティを処理できます。

結果(背景セレクタは使用されませんでした)。

通常ボタン

通常の画像

押されたボタン

ここに画像の説明を入力してください


0

うまく機能する別のスタイルのボタンを作成する方法は、Buttonオブジェクトをサブクラス化し、カラーフィルターを適用することです。これは、ボタンにアルファを適用することにより、有効および無効の状態も処理します。

import android.annotation.TargetApi;
import android.content.Context;
import android.graphics.Color;
import android.graphics.ColorFilter;
import android.graphics.LightingColorFilter;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.LayerDrawable;
import android.os.Build;
import android.util.AttributeSet;
import android.widget.Button;

public class DimmableButton extends Button {

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

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

    public DimmableButton(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    @SuppressWarnings("deprecation")
    @Override
    public void setBackgroundDrawable(Drawable d) {
        // Replace the original background drawable (e.g. image) with a LayerDrawable that
        // contains the original drawable.
        DimmableButtonBackgroundDrawable layer = new DimmableButtonBackgroundDrawable(d);
        super.setBackgroundDrawable(layer);
    }

    @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
    @Override
    public void setBackground(Drawable d) {
        // Replace the original background drawable (e.g. image) with a LayerDrawable that
        // contains the original drawable.
        DimmableButtonBackgroundDrawable layer = new DimmableButtonBackgroundDrawable(d);
        super.setBackground(layer);
    }

    /**
     * The stateful LayerDrawable used by this button.
     */
    protected class DimmableButtonBackgroundDrawable extends LayerDrawable {

        // The color filter to apply when the button is pressed
        protected ColorFilter _pressedFilter = new LightingColorFilter(Color.LTGRAY, 1);
        // Alpha value when the button is disabled
        protected int _disabledAlpha = 100;
        // Alpha value when the button is enabled
        protected int _fullAlpha = 255;

        public DimmableButtonBackgroundDrawable(Drawable d) {
            super(new Drawable[] { d });
        }

        @Override
        protected boolean onStateChange(int[] states) {
            boolean enabled = false;
            boolean pressed = false;

            for (int state : states) {
                if (state == android.R.attr.state_enabled)
                    enabled = true;
                else if (state == android.R.attr.state_pressed)
                    pressed = true;
            }

            mutate();
            if (enabled && pressed) {
                setColorFilter(_pressedFilter);
            } else if (!enabled) {
                setColorFilter(null);
                setAlpha(_disabledAlpha);
            } else {
                setColorFilter(null);
                setAlpha(_fullAlpha);
            }

            invalidateSelf();

            return super.onStateChange(states);
        }

        @Override
        public boolean isStateful() {
            return true;
        }
    }

}

0

values \ styles.xml

<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
    <item name="colorPrimary">@color/colorPrimary</item>
    <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
    <item name="colorAccent">@color/colorAccent</item>
</style>

<style name="RedAccentButton" parent="ThemeOverlay.AppCompat.Light">
    <item name="colorAccent">#ff0000</item>
</style>

次に:

<Button
    style="@style/Widget.AppCompat.Button.Colored"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="text" />

<Button
    style="@style/Widget.AppCompat.Button.Colored"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:enabled="false"
    android:text="text" />

<Button
    style="@style/Widget.AppCompat.Button.Colored"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="text"
    android:theme="@style/RedAccentButton" />

<Button
    style="@style/Widget.AppCompat.Button.Colored"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:enabled="false"
    android:text="text"
    android:theme="@style/RedAccentButton" />

結果


0

材料設計ガイドラインに従って、以下のコードのようなスタイルを使用する必要があります

<style name="MyButton" parent="Theme.AppCompat.Light>
    <item name="colorControlHighlight">#F36F21</item>
    <item name="colorControlHighlight">#FF8D00</item>
</style>

レイアウトでこのプロパティをボタンに追加します

    android:theme="@style/MyButton"

0

シンプルです。この依存関係をプロジェクトに追加し、1。任意の形状2.任意の色3.任意の境界線4.マテリアル効果を持つボタンを作成します。

https://github.com/manojbhadane/QButton

<com.manojbhadane.QButton
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:text="OK"
       app:qb_backgroundColor="@color/green"
       app:qb_radius="100"
       app:qb_strokeColor="@color/darkGreen"
       app:qb_strokeWidth="5" />
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.