クライアントのブランドによく合うように、標準のAndroidボタンの色を少し変更します。
私がこれまでにこれを行うことを見つけた最もよい方法はButton
のdrawableをres/drawable/red_button.xml
にあるdrawableに変えることです:
<?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つは押されたとき)。それは私が必要としているよりももっと複雑で乾いていないようです。
私が本当にやりたいことはボタンにある種の色変換を適用することだけです。ボタンの色を変更するよりも簡単な方法はありますか。
私はこれがすべて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>
Tomaszの答えに続いて、PorterDuffの乗算モードを使ってプログラム的にボタン全体の色合いを設定することもできます。これは単に色合いではなくボタンの色を変えるでしょう。
標準的なグレーの網掛けのボタンから始めると:
button.getBackground().setColorFilter(0xFFFF0000, PorterDuff.Mode.MULTIPLY);
赤い網掛けのボタンが表示されます。
button.getBackground().setColorFilter(0xFF00FF00, PorterDuff.Mode.MULTIPLY);
最初の値は16進形式の色です。
現在のボタンの色の値に自分の色の値を掛けて機能します。これらのモードでできることは他にもたくさんあると思います。
マイク、あなたはカラーフィルターに興味があるかもしれません。
例:
button.getBackground().setColorFilter(new LightingColorFilter(0xFFFFFFFF, 0xFFAA0000));
あなたが望む色を達成するためにこれを試みなさい。
これは私の解決策であり、API 15からで完全に機能します。このソリューションは、material RippleEffect
のように、すべてのデフォルトのボタンクリック効果を維持します。私はより低いAPIでそれをテストしていませんが、それはうまくいくはずです。
あなたがする必要があるのは、ただです:
1)colorAccent
のみを変更するスタイルを作成します。
<style name="Facebook.Button" parent="ThemeOverlay.AppCompat">
<item name="colorAccent">@color/com_facebook_blue</item>
</style>
残りのスタイルを維持するために、
ThemeOverlay.AppCompat
またはメインのAppTheme
を親として使用することをお勧めします。
2)これら2行をbutton
ウィジェットに追加してください。
style="@style/Widget.AppCompat.Button.Colored"
Android:theme="@style/Facebook.Button"
新しい
colorAccent
がAndroid Studio Previewに表示されないことがありますが、電話でアプリを起動すると色が変わります。
<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" />
backgroundTint
属性と共にappcompat-v7の AppCompatButton を使用することもできます。
<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"/>
私は@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();
}
});
私はこれを複数のボタンに適用するための独立したクラスとして抽出しました - アイデアを得るために匿名の内部クラスとして表示されています。
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>
私はこの方法を使っています
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:background
を設定するよりもはるかに良いアプローチであると思います。Googleが提供する波及効果を失うことはないからです。
このように使用してください。
buttonOBJ.getBackground().setColorFilter(Color.parseColor("#YOUR_HEX_COLOR_CODE"), PorterDuff.Mode.MULTIPLY);
今はるかに簡単な方法があります: Android-holo-colors.com
それはあなたが簡単にすべてのホロのドロアブル(ボタン、スピナーなど)の色を変えることを可能にするでしょう。色を選択してから、すべての解像度のドロアブルを含むZipファイルをダウンロードします。
<Button>
ではAndroid:background="#33b5e5"
を使用してください。 Android:background="@color/navig_button"
以上
また、このオンラインツールを使用してボタンをカスタマイズすることもできます http://angrytools.com/Android/button/ そしてAndroid:background="@drawable/custom_btn"
を使用してレイアウト内のカスタマイズされたボタンを定義することもできます。
DroidUX componentライブラリには ColorButton
ウィジェットがあり、その色はxml定義とプログラム実行時の両方で簡単に変更できるので、アプリの場合はユーザーにボタンの色/テーマを設定させることもできますそれを許可します。
ボタンのテーマをこれに設定できます
<style name="AppTheme.ButtonBlue" parent="Widget.AppCompat.Button.Colored">
<item name="colorButtonNormal">@color/HEXColor</item>
<item name="Android:textColor">@color/HEXColor</item>
</style>
簡単な方法は、カスタムのButtonクラスを定義するだけで、半径、グラデーション、押された色、通常の色など、希望するすべてのプロパティを受け入れ、それをXMLを使用して背景を設定する代わりにXMLレイアウトで使用することです。サンプルは ここ
半径や選択した色など、同じプロパティを持つボタンがたくさんある場合、これは非常に便利です。継承されたボタンをカスタマイズしてこれらの追加のプロパティを処理できます。
結果(バックグラウンドセレクタは使用されていません).
通常のボタン
押されたボタン
材料設計のガイドラインに従って、以下のようなスタイルを使用する必要があります
<style name="MyButton" parent="Theme.AppCompat.Light>
<item name="colorControlHighlight">#F36F21</item>
<item name="colorControlHighlight">#FF8D00</item>
</style>
レイアウトでこのプロパティをボタンに追加します
Android:theme="@style/MyButton"
そのシンプルな..あなたのプロジェクトにこの依存関係を追加して、1でボタンを作成します。
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" />
私は非常にうまく機能する別のスタイルのボタンを行う方法は、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;
}
}
}
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" />