Od jakiegoś czasu próbuję prześledzić ten problem. Chyba znalazłem jakieś wyjaśnienie jakiś czas temu. Niestety, zagubione w komentarzach kodu gdzieś.Program RippleDrawable programowo wygląda inaczej niż jego odpowiednik xml
Próbuję utworzyć Material Borderless-Button
w Javie. Na początek, oto co przycisk wygląda w ramach:
Przycisk bg (button_borderless_material.xml):
<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="?attr/colorControlHighlight">
<item android:id="@id/mask"
android:drawable="@drawable/btn_default_mtrl_shape" />
</ripple>
drawable
używany jako maska (btn_default_mtrl_shape.xml):
<?xml version="1.0" encoding="utf-8"?>
<!-- Used as the canonical button shape. -->
<inset xmlns:android="http://schemas.android.com/apk/res/android"
android:insetLeft="@dimen/button_inset_horizontal_material"
android:insetTop="@dimen/button_inset_vertical_material"
android:insetRight="@dimen/button_inset_horizontal_material"
android:insetBottom="@dimen/button_inset_vertical_material">
<shape android:shape="rectangle"
android:tint="?attr/colorButtonNormal">
<corners android:radius="@dimen/control_corner_material" />
<solid android:color="@color/white" />
<padding android:left="@dimen/button_padding_horizontal_material"
android:top="@dimen/button_padding_vertical_material"
android:right="@dimen/button_padding_horizontal_material"
android:bottom="@dimen/button_padding_vertical_material" />
</shape>
</inset>
Java odpowiednik inset-drawable
(btn_default_mtrl_shape.xml):
Drawable createButtonShape(Context context, int color) {
Resource res = context.getResources();
int radius = res
.getDimensionPixelSize(R.dimen.control_corner_material);
int paddingH = res
.getDimensionPixelSize(R.dimen.button_padding_horizontal_material);
int paddingV = res
.getDimensionPixelSize(R.dimen.button_padding_vertical_material);
int insetH = context.getResources()
.getDimensionPixelSize(R.dimen.button_inset_horizontal_material);
int insetV = res
.getDimensionPixelSize(R.dimen.button_inset_vertical_material);
float[] outerRadii = new float[8];
Arrays.fill(outerRadii, radius);
RoundRectShape r = new RoundRectShape(outerRadii, null, null);
ShapeDrawable shapeDrawable = new ShapeDrawable(r);
shapeDrawable.getPaint().setColor(color);
shapeDrawable.setPadding(paddingH, paddingV, paddingH, paddingV);
return new InsetDrawable(shapeDrawable,
insetH, insetV, insetH, insetV);
}
color
argumentem jest otrzymywany z motywu attr/colorButtonNormal
- tego samego koloru używanego z android:tint
w definicji xml.
RippleDrawable
tworzone programowo:
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
Drawable createButtonRippleBg(Context context,
int colorButtonNormal,
int colorControlHighlight) {
return new RippleDrawable(ColorStateList.valueOf(colorControlHighlight),
null, createButtonShape(context, colorButtonNormal));
}
Zdaję sobie sprawę, że choć maska-kolor/kształt nie jest renderowany wizualnie, jego alfa ma wpływa na RippleDrawable
. To nie jest problem - wszystkie kolory używane w masce mają pełnowymiarową alfę.
Potwierdziłem również, że kolory odczytane z atrybutów - colorControlHighlight & colorButtonNormal
- są poprawne dla motywu podczas gry.
Jednak wynik jest:
Xml wydania:
W Javie:
Ciekawe bit jest, że dzieje się na 21. Na API API 22, oba podejścia dają identyczne wyniki.
Pytanie:
Jestem pewien, że jest to błąd na API 21. Jeśli ktoś może to wyśledzić, możemy prawdopodobnie mnożnik dla wartości alfa/koloru, aby zrównoważyć tę różnicę wizualną.
Oprócz ogólnej dobrej woli, obiecuję również nagrodę, ponieważ już poświęciłem temu trochę czasu.
Jedyna różnica widzę jest to, że poprzez XML ustawić kolor jako odcień 'android:„attr/colorButtonNormal”odcień =' i za pośrednictwem kodu go ustawić jako kolor 'shapeDrawable. getPaint().setColor (color); ' – mikepenz
@mikepenz Yea, argument' color' jest faktycznie uzyskiwany z 'colorButtonNormal '. Wspomniałem o tym wyżej: _Kolejny "kolor" uzyskuje się z 'attr/colorButtonNormal 'tego samego koloru, co w przypadku' android: tint' w definicji xml. – Vikram
Nie, nie o to mi chodzi. Ustawiasz go jako kolor 'shapeDrawable.getPaint(). SetColor (color)' w xml jako 'tint'. dlaczego nie ustawić go jako odcień za pomocą kodu? 'shapeDrawable.setTint();' – mikepenz