私のリップルには次のコードがあります:
<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:color="?android:colorControlHighlight">
<item Android:id="@+id/rip">
<shape Android:shape="oval">
<solid Android:color="?android:colorAccent"/>
</shape>
</item>
</ripple>
ここで、ユーザーに独自の色を選択できるようにしたいので、プログラムでリップルを作成する必要があります。
私は this を見つけました。これが正しい方法だと思いますが、これをどう扱うかはわかりません。
リップルはここで使用されます:
<ImageButton
Android:id="@+id/add_button"
Android:layout_width="@dimen/diameter"
Android:layout_height="@dimen/diameter"
Android:layout_gravity="end|bottom"
Android:layout_marginBottom="@dimen/add_button_margin"
Android:layout_marginEnd="@dimen/add_button_margin"
Android:layout_alignParentBottom="true"
Android:layout_alignParentEnd="true"
Android:src="@drawable/ic_action_add_person"
Android:tint="@Android:color/white"
Android:background="@drawable/oval_ripple"
Android:elevation="@dimen/elevation_low"
Android:stateListAnimator="@anim/button_elevation"
Android:contentDescription="Neuer Spieler" />
このように背景をRippleDrawable
に設定する必要があります。
addButton.setBackground(ripple);
これは私がこれを達成することができた方法です。
これはApi 21+のみであるため、以前のバージョンをサポートする場合は通常のDrawableにフォールバックする必要があることに注意してください。
public static RippleDrawable getPressedColorRippleDrawable(int normalColor, int pressedColor)
{
return new RippleDrawable(getPressedColorSelector(normalColor, pressedColor), getColorDrawableFromColor(normalColor), null);
}
public static ColorStateList getPressedColorSelector(int normalColor, int pressedColor)
{
return new ColorStateList(
new int[][]
{
new int[]{Android.R.attr.state_pressed},
new int[]{Android.R.attr.state_focused},
new int[]{Android.R.attr.state_activated},
new int[]{}
},
new int[]
{
pressedColor,
pressedColor,
pressedColor,
normalColor
}
);
}
public static ColorDrawable getColorDrawableFromColor(int color)
{
return new ColorDrawable(color);
}
編集:私はこれをさらにいじり、ColorStateListが上記のソリューションほど複雑である必要はないことを発見しました。以下のスニペットに簡略化しました。 (上記のコードブロックの他のすべては同じです。ColorStateListの作成を変更しただけです。)このメソッドが誰かのために機能しない場合に備えて、上記のブロックを元のままにします。
new ColorStateList(
new int[][]
{
new int[]{}
},
new int[]
{
pressedColor
}
);
public static Drawable getAdaptiveRippleDrawable(
int normalColor, int pressedColor) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Lollipop) {
return new RippleDrawable(ColorStateList.valueOf(pressedColor),
null, getRippleMask(normalColor));
} else {
return getStateListDrawable(normalColor, pressedColor);
}
}
private static Drawable getRippleMask(int color) {
float[] outerRadii = new float[8];
// 3 is radius of final ripple,
// instead of 3 you can give required final radius
Arrays.fill(outerRadii, 3);
RoundRectShape r = new RoundRectShape(outerRadii, null, null);
ShapeDrawable shapeDrawable = new ShapeDrawable(r);
shapeDrawable.getPaint().setColor(color);
return shapeDrawable;
}
public static StateListDrawable getStateListDrawable(
int normalColor, int pressedColor) {
StateListDrawable states = new StateListDrawable();
states.addState(new int[]{Android.R.attr.state_pressed},
new ColorDrawable(pressedColor));
states.addState(new int[]{Android.R.attr.state_focused},
new ColorDrawable(pressedColor));
states.addState(new int[]{Android.R.attr.state_activated},
new ColorDrawable(pressedColor));
states.addState(new int[]{},
new ColorDrawable(normalColor));
return states;
}
view.setDrawable
を使用して、ドロアブルを取得し、任意のビューに適用できます。
Lollipop +デバイスの場合、波紋が発生します。さもなければ、ビューの色が変わります。
基本的に、新しいRippleDrawableオブジェクトを作成する必要があります。 Lollipop以前のデバイスの場合、StateListDrawableが必要です(他の人が既に提案しているように)。 Drawableと色付けに関連する便利なメソッドの束を使って、やや機知に富んだGistを書きました: https://Gist.github.com/milosmns/6566ca9e3b756d922aa5
ほとんどの場合、そのシングルトンから#getBackgroundDrawable()
を使用する必要があります。