背景色のボタンのマテリアル効果


246

Android v21サポートライブラリを使用しています。

カスタム背景色のボタンを作成しました。リップル、リビールなどのマテリアルデザイン効果は、背景色を使用すると消えます(クリック時の高度を除く)。

 <Button
 style="?android:attr/buttonStyleSmall"
 android:background="?attr/colorPrimary"
 android:textColor="@color/white"
 android:textAllCaps="true"
 android:layout_width="fill_parent"
 android:layout_height="wrap_content"
 android:text="Button1"
 />

バックグラウンド 以下は通常のボタンで、効果は問題なく機能しています。

<Button
 style="?android:attr/buttonStyleSmall"
 android:layout_width="fill_parent"
 android:layout_height="wrap_content"
 android:textAllCaps="true"
 android:text="Button1"
/>

デフォルトボタン


9
これは、背景を無地のすべての素敵なマテリアル効果で置き換えるために発生します。マテリアルエフェクトを維持しながらボタンに適切に色を付ける方法については、SOの誰もまだそれを理解できていません。
Nathan Walters、2014年

2
@SweetWisher背景色を変更すると、ボタンに波紋やその他の効果が適用されません。
Sathesh 2014年

1
@NathanWaltersしかし、デフォルトの灰色は醜いです。:-(
Sathesh 2014年

6
私を信じて、私は知っています...これを適切に行う方法を理解する人には誰でも大きな負債があります。
Nathan Walters、2014年

回答:


431

を使用するandroid:backgroundと、ボタンのスタイリングとルックアンドフィールの多くが空白の色に置き換わります。

更新:のようバージョン23.0.0リリースAPPCOMPAT、新しいそこにあるWidget.AppCompat.Button.Colored、あなたのテーマのスタイルを使用してcolorButtonNormal無効になった色のためにとcolorAccent色を有効にするためには。

これにより、ボタンに直接適用できます

<Button
  ...
  style="@style/Widget.AppCompat.Button.Colored" />

カスタムcolorButtonNormalまたはが必要な場合は、このプロチップとボタンで説明されてcolorAccentいるThemeOverlayを使用できます。android:theme

前の回答

次のような背景には、v21ディレクトリのドローアブルを使用できます。

<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
        android:color="?attr/colorControlHighlight">
    <item android:drawable="?attr/colorPrimary"/>
</ripple>

これにより、背景色が?attr/colorPrimaryデフォルトになり、デフォルトを使用してデフォルトのリップルアニメーション?attr/colorControlHighlightが設定されます(必要に応じてテーマに設定することもできます)。

注:v21未満のカスタムセレクターを作成する必要があります。

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

デフォルト、押された、フォーカスされた状態にしたい色があると仮定します。個人的に、私は選択されている途中の波紋のスクリーンショットを撮り、その中から主要な/集中した状態を引き出しました。


13
素敵な答え!まさに私が探していたものですが、プロジェクトがdrawable-v21でドローアブルを識別することを決定する前に、クリーニングと再構築が必要でした。
user1354603 2014年


4
@ianhanniballakeこれらのボタンで丸みを帯びた角のカスタマイズを失うことなく、この作業テクニックを組み合わせる方法を思います
Joaquin Iurchuk

3
@ianhanniballakeは単なるコメントであり、<item android:drawable ... />の下のリップルで描画可能です。透明色にすることはできません。その場合、リップルは表示されません。それを理解するのにしばらく時間がかかりました。
IvanKušt2015

2
appcompat 23.1.1とAPI 22では、無効と有効の両方の状態がテーマのcolorButtonNormal色を取ります。
レミーDAVID

93

「Material」効果を維持しながら「Flat」ボタンのカスタム背景を提供する別の簡単なソリューションがあります。

  1. 目的の背景を設定して、ViewGroupにボタンを配置します
  2. セットselectableItemBackgroundあなたのボタンの背景として、現在のテーマから(API> = 11)

すなわち:

<FrameLayout
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="@color/blue">
    <Button
        style="?android:attr/buttonStyleSmall"
        android:background="?android:attr/selectableItemBackground"
        android:textColor="@android:color/white"
        android:textAllCaps="true"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="Button1"
        />
</FrameLayout>

フラットボタンに使用でき、API> = 11で機能します。21以上のデバイスでリップル効果が得られ、AppCompatが更新されてそこでリップルもサポートされるまで、通常のボタンを21未満で維持します。

selectableItemBackgroundBorderlessを21以上のボタンにのみ使用することもできます。


あなたは文字通り箱から出して考えました:-)これはこれを行う1つの方法ですが、コードの結合を増やす可能性があり、スタイルの使用が推奨される方法です。
Sathesh 2015年

3
これで、背景が色のフラットボタンが作成されます。しかし、作成されたボタンは四角のように見え、角が丸く、影の効果はありません。
Sanket Berde 2015

7
@SanketBerdeその通りです。「フラット」ボタンとはそういうものです。
kiruwka

2
元の質問では、フラットについては触れられていませんでした。ところで、ソリューションに<FrameLayout>の代わりに<CardView>親がある場合、結果のボタンは発生し、影が付きます。これはロリポップ前のバージョンでも機能します。
Sanket Berde 2015

1
@SanketBerde CardViewアプローチについて知って素晴らしい、共有してくれてありがとう!
キルカ2015年

88

これは、カスタム背景を持つ隆起したボタンにリップル効果を提供するためのシンプルで下位互換性のある方法です。

レイアウトは次のようになります

<Button
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="@drawable/my_custom_background"
    android:foreground="?android:attr/selectableItemBackground"/>

9
これは、これを達成するための最も簡単で手間のかからない方法です。いい答えだ。
タイラーPfaff

1
api 21+が機能していません。clickable-true、background-異なる色、foreground-を指定した線形レイアウトに適用されます。
アレックス、

3
ボタンがTextViewのといないでframeLayoutあるので、foreground23の前に何も影響ありませんgoogle.com/...を
androidguy

2
いいね!「前景」が何かであることさえ知りませんでした!
エリックシュレンツ2017年

2
チャームのように動作します。
カンナン

25

今日、この問題に遭遇し、実際にv22ライブラリを実際に遊んでいました。

スタイルを使用していると仮定すると、colorButtonNormalプロパティを設定でき、ボタンはデフォルトでその色を使用します。

<style name="AppTheme" parent="BaseTheme">
    <!-- Customize your theme here. -->
    <item name="colorPrimary">@color/primaryColor</item>
    <item name="colorPrimaryDark">@color/primaryColorDark</item>
    <item name="colorAccent">@color/accentColor</item>
    <item name="colorButtonNormal">@color/primaryColor</item>
</style>

それ以外では、ボタンのスタイルを作成し、色の組み合わせが必要な場合は、ボタンごとにそのスタイルを使用することができます(テストせず、推測のみ)。

v21スタイルのandroid:アイテム名の前に必ず追加してください。


色付きのボタンの種類については、他のRobertの回答を参照してください:stackoverflow.com/a/31825439/1617737
ban-geoengineering

これで背景色が設定されましたが、上記のコードブロックでボタンのテキストの色を指定するために使用できる一般的な属性もありますか?
ban-geoengineering 2017年

24

AppCompat(22.1.1+)を使用すると、次のようなスタイルを追加できます。

<style name="MyGreenButton">
    <item name="colorButtonNormal">#009900</item>
</style>

スタイルを適用するだけで使用できます。

<android.support.v7.widget.AppCompatButton
    style="@style/MyGreenButton"
    android:layout_width="match_width"
    android:layout_height="wrap_content"
    android:text="A Green Button"
    />

プログラムで色を変更すると、(API 15または16で)色を更新する唯一の方法は、代わりに「背景色合いリスト」を使用することでした。そして、それはAPI 21デバイスの素敵な放射状アニメーションを削除しません:

ColorStateList colorStateList = new ColorStateList(new int[][] {{0}}, new int[] {0xFF009900}); // 0xAARRGGBB
button.setSupportBackgroundTintList(colorStateList);

ためbutton.setBackground(...)button.getBackground().mutate().setColorFilter(...)、彼らはAPI 21上で行うようにAPI 15及び16上のボタンの色を変更しないでください。


1
どうもありがとうございました(AppCompatインフレーターがAppCompatButtonで置き換えられたxmlレイアウトでButtonを使用した場合でも)
Louis CAD

1
1色のみのColorStateList.valueOf( ... )単純なColorStateList色を作成するために使用します。
Taig

colorAccentとリップルカラーがスタイルで機能しない
Yar

この投稿をありがとう。私にとってうまくいったこと:ViewCompat.setBackgroundTintList(myButton, ColorStateList.valueOf(myColor); Javadoc setSupportBackgroundTintListは、このように呼ばれるべきだと言っています。
JerabekJakub 2017年

22

@ianhanniballakeの答えは完全に正しく、シンプルです。しかし、理解するのに数日かかりました。彼の答えを理解していない人のために、これはより詳細な実装です

<Button
        android:id="@+id/btn"
        style="@style/MaterialButton"
        ... />


<style name="MaterialButton" parent="Widget.AppCompat.Button.Colored">
    <item name="android:theme">@style/Theme.MaterialButton</item>
   ...
</style>


<style name="Theme.MaterialButton" parent="YourTheme">
    <item name="colorAccent">@color/yourAccentColor</item>
    <item name="colorButtonNormal">@color/yourButtonNormalColor</item>
</style>

===または===

<Button
        android:id="@+id/btn"
        style="@style/Widget.AppCompat.Button.Colored"
        android:theme="@style/Theme.MaterialButton" />

<style name="Theme.MaterialButton" parent="YourTheme">
    <item name="colorAccent">@color/yourAccentColor</item>
    <item name="colorButtonNormal">@color/yourButtonNormalColor</item>
</style>

5
あなたの答えは私にとってパズルの最後のピースでした。またcolorButtonNormal、基本テーマを書き込むこともでき@style/AppThemeます。これにより、AppCompatにデフォルトの色が与えられ、それに応じてボタンに色が付けられます。そして、あなたの答えを使用して、ビューのテーマを個別に設定できます。
Siddharth Pant 2016年

1
それandroid:theme="Theme.MaterialButton"android:theme="@style/Theme.MaterialButton"
osrl 2016年

1
@osrlですandroid:theme="@style/Theme.MaterialButton"。あなたの正確さをありがとう。
フランク・グエン2017

12

私はbackgroundTintとforegroundを使用しました:

<Button
    android:layout_width="match_parent"
    android:layout_height="40dp"
    android:backgroundTint="@color/colorAccent"
    android:foreground="?android:attr/selectableItemBackground"
    android:textColor="@android:color/white"
    android:textSize="10sp"/>

afaik backgroundTintは標準のリップルを上書きしないため、前景属性は必要ありません
Julian Os

7

私はこの記事に来て、私のListViewアイテムの背景色を取りながら、波紋を維持する方法を探しました。

私は単に背景として色を追加し、前景としてselectableItemBackgroundを追加しました。

<style name="my_list_item">
    <item name="android:background">@color/white</item>
    <item name="android:foreground">?attr/selectableItemBackground</item>
    <item name="android:layout_height">@dimen/my_list_item_height</item>
</style>

そしてそれは魅力のように働きます。ボタンにも同じテクニックが使えると思います。幸運を :)



6

ImageButtonに興味がある場合は、次の簡単な方法を試すことができます。

<ImageButton
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:src="@android:drawable/ic_button"
    android:background="?attr/selectableItemBackgroundBorderless"
/>

5

v22.1appcompat-v7いくつかの新たな可能性を導入しました。特定のテーマを1つのビューにのみ割り当てることができるようになりました。

ツールバーのスタイル設定のためのapp:themeの非推奨の使用。すべてのAPIレベル7以降のデバイスのツールバーにandroid:themeを使用できるようになり、APIレベル11以降のデバイスのすべてのウィジェットにandroid:themeサポートを使用できるようになりました。

したがって、グローバルテーマで目的の色を設定する代わりに、新しい色を作成して、それを Button

例:

<style name="MyColorButton" parent="Theme.AppCompat.Light.DarkActionBar">
        <item name="colorButtonNormal">@color/myColor</item>
</style>

そして、あなたのテーマとしてこのスタイルを使用してください Button

<Button
 style="?android:attr/buttonStyleSmall"
 android:layout_width="fill_parent"
 android:layout_height="wrap_content"
 android:text="Button1"
 android:theme="@style/MyColorButton"/>

4

サードパーティのライブラリを使用することに問題がなければ、traex / RippleEffectをチェックしてください。それはあなたがに波及効果を追加することができますANYわずか数行のコードで表示。com.andexert.library.RippleViewコンテナーで波及効果を持たせたい要素をxmlレイアウトファイルにラップするだけです。

追加のボーナスとして、Min SDK 9が必要になるため、OSのバージョン間で設計の一貫性を保つことができます。

これは、ライブラリのGitHubリポジトリから取得した例です。

<com.andexert.library.RippleView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    app:rv_centered="true">

    <ImageView
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:src="@android:drawable/ic_menu_edit"
        android:background="@android:color/holo_blue_dark"/> 

</com.andexert.library.RippleView>

この属性をRippleView要素に追加することで、波紋の色を変更できます。 app:rv_color="@color/my_fancy_ripple_color


3
<android.support.v7.widget.AppCompatButton
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    app:backgroundTint="#fff"
    android:textColor="#000"
    android:text="test"/>

使用する

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

そして色はプレロリポップを受け入れます


2

Alex Lockwoodの素晴らしいチュートリアルで説明されている2つのアプローチがあります:http : //www.androiddesignpatterns.com/2016/08/coloring-buttons-with-themeoverlays-background-tints.html :

アプローチ1:ボタンの背景色をThemeOverlayで変更する

<!-- res/values/themes.xml -->
<style name="RedButtonLightTheme" parent="ThemeOverlay.AppCompat.Light">
    <item name="colorAccent">@color/googred500</item>
</style>

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

アプローチ#2:AppCompatButtonの背景色の設定

<!-- res/color/btn_colored_background_tint.xml -->
<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <!-- Disabled state. -->
    <item android:state_enabled="false"
          android:color="?attr/colorButtonNormal"
          android:alpha="?android:attr/disabledAlpha"/>

    <!-- Enabled state. -->
    <item android:color="?attr/colorAccent"/>

</selector>

<android.support.v7.widget.AppCompatButton
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    app:backgroundTint="@color/btn_colored_background_tint"/>

2

プログラムで色を適用する:

if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {

    ColorStateList colorStateListRipple = new ColorStateList(
            new int[][] {{0}},
            new int[] {Color.WHITE} // ripple color
            );

    RippleDrawable rippleDrawable = (RippleDrawable) myButton.getBackground();
    rippleDrawable.setColor(colorStateListRipple);
    myButton.setBackground(rippleDrawable); // applying the ripple color
}

ColorStateList colorStateList = new ColorStateList(
        new int[][]{
                new int[]{android.R.attr.state_pressed}, // when pressed
                new int[]{android.R.attr.state_enabled}, // normal state color
                new int[]{} // normal state color
        },
        new int[]{
                Color.CYAN, // when pressed
                Color.RED, // normal state color
                Color.RED // normal state color
        }
);

ViewCompat.setBackgroundTintList(myButton, colorStateList); // applying the state colors

-1

私はこれを試しました:

android:backgroundTint:"@color/mycolor"

背景のプロパティを変更する代わりに。これは、マテリアル効果を削除しません。


これはLollipop以前のデバイスでは機能しません(70%の市場シェア)。実際にはバックポートされていますが、現時点でAndroid Studioは、androidプレフィックスなしで使用するとエラーを表示します。
Siddharth Pant 2016年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.