Как использовать RippleDrawable программно в коде (не xml) с Android 5.0 Lollipop?
у меня есть следующий код для моего пульсации:
<?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>
теперь я хочу дать пользователю возможность выбрать собственные цвета, поэтому мне нужно, чтобы создать пульсации программно.
Я нашел этой и я думаю, что это правильный способ сделать это, но я не знаю как справиться с этим.
пульсация будет использоваться здесь:
<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);
3 ответов
вот как я смог этого достичь.
обратите внимание, что это 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);
}
Edit: Я еще немного повозился с этим и обнаружил, что 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;
}
вы можете получить drawable и применить к любому виду, используя view.setDrawable
.
Для устройств Lollipop+ вы получите пульсацию, иначе она изменит цвет вида.
в принципе, вам нужно создать новый объект RippleDrawable. Для устройств pre-Lollipop вам нужен StateListDrawable (как уже предлагали другие). Я написал несколько находчивый GIST с кучей полезных методов, связанных с Drawables и coloring: https://gist.github.com/milosmns/6566ca9e3b756d922aa5
скорее всего, вы захотите использовать #getBackgroundDrawable()
от одноплодной.