Ho cercato di rintracciare questo problema per un po 'di tempo. Penso di aver trovato una spiegazione qualche tempo fa. Sfortunatamente, è stato perso nei commenti di codice da qualche parte.RippleDrawable creato a livello di codice sembra diverso dalla sua controparte xml
Sto cercando di creare un Material Borderless-Button
in Java. Per cominciare, ecco cosa il pulsante appare come nel quadro:
Pulsante 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>
Il drawable
essere usato come maschera (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 equivalente del 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);
}
L'argomento color
è ottenuto dalla tema di attr/colorButtonNormal
- lo stesso colore utilizzato con android:tint
nella definizione XML.
Il RippleDrawable
creato a livello di codice:
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
Drawable createButtonRippleBg(Context context,
int colorButtonNormal,
int colorControlHighlight) {
return new RippleDrawable(ColorStateList.valueOf(colorControlHighlight),
null, createButtonShape(context, colorButtonNormal));
}
Sono consapevole del fatto che, anche se la maschera-colore/forma non è reso visivamente, la sua alfa fa influisce sulla RippleDrawable
. Questo non è un problema qui: tutti i colori usati per la maschera hanno un alfa completo.
Ho anche confermato che i colori letti dagli attributi - colorControlHighlight & colorButtonNormal
- sono corretti per il tema in gioco.
Tuttavia, il risultato è:
XML resa:
In Java:
bit interessante è che questo avviene API 21. API 22, entrambi gli approcci producono risultati identici.
La domanda:
Sono certo che si tratta di un bug su API 21. Se qualcuno può seguire questo giù, si può probabilmente trovare un moltiplicatore per il valore alfa/colore per compensare questa differenza visiva.
Oltre alla buona volontà generale, prometto anche un premio in quanto ho già trascorso un po 'di tempo su questo.
L'unica differenza che vedo è che via XML di impostare il colore come tinta 'Android: "attr/colorButtonNormal" tinta =' e tramite codice si imposta come colore 'shapeDrawable. getPaint().setColor (color); ' – mikepenz
@mikepenz Sì, l'argomento' color' è in realtà ottenuto da 'colorButtonNormal' del tema. L'ho detto sopra: _L'argomento 'color' è ottenuto dal tema' attr/colorButtonNormal' - lo stesso colore usato con 'android: tint' in xml definition_. – Vikram
no, questa non è la cosa che intendo. Lo si imposta come colore 'shapeDrawable.getPaint(). SetColor (color)' nel xml come 'tint'. perché non impostarlo anche come tinta tramite codice? 'shapeDrawable.setTint();' – mikepenz