Notez que les pourcentages de gradientRadius fonctionnent dans Lollipop. Mais si vous devez prendre en charge les versions antérieures à Lollipop, j'ai développé la réponse de @marnaish en ajoutant des attributs XML. Mon gradientRadius est défini comme un pourcentage de la largeur de la vue parent :
public class RadialGradientView extends View {
private final int endColor;
private final int startColor;
private final float gradientRadiusWidthPercent;
private final float centerY;
private final float centerX;
private Paint paint;
public RadialGradientView(Context context, AttributeSet attrs) {
super(context, attrs);
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.RadialGradientView, 0, 0);
startColor = a.getColor(R.styleable.RadialGradientView_startColor, Color.RED);
endColor = a.getColor(R.styleable.RadialGradientView_endColor, Color.BLACK);
gradientRadiusWidthPercent = a.getFloat(R.styleable.RadialGradientView_gradientRadiusWidthPercent, 1);
centerX = a.getFloat(R.styleable.RadialGradientView_centerX, .5f);
centerY = a.getFloat(R.styleable.RadialGradientView_centerY, .5f);
a.recycle();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int parentWidth = MeasureSpec.getSize(widthMeasureSpec);
int parentHeight = MeasureSpec.getSize(heightMeasureSpec);
paint = new Paint(Paint.ANTI_ALIAS_FLAG);
RadialGradient gradient = new RadialGradient(
parentWidth*centerX,
parentHeight*centerY,
parentWidth*gradientRadiusWidthPercent,
new int[] {startColor, endColor},
null,
android.graphics.Shader.TileMode.CLAMP);
paint.setDither(true);
paint.setShader(gradient);
}
@Override
protected void onDraw(Canvas canvas) {
canvas.drawRect(0, 0, getWidth(), getHeight(), paint);
}
}
Dans attrs.xml :
<declare-styleable name="RadialGradientView">
<attr name="startColor" format="color|reference"/>
<attr name="endColor" format="color|reference"/>
<attr name="gradientRadiusWidthPercent" format="float"/>
<attr name="centerX" format="float"/>
<attr name="centerY" format="float"/>
</declare-styleable>
Malheureusement, il n'est pas possible de créer une table traçable XML à partir d'une classe personnalisée, ce qui signifie que vous ne pouvez pas la définir comme arrière-plan Android:background d'une vue. La solution de contournement consiste à utiliser un FrameLayout pour le superposer comme arrière-plan.
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="100dp">
<com.RadialGradientView
android:layout_width="match_parent"
android:layout_height="match_parent"
app:centerX=".3"
app:centerY=".5"
app:endColor="#0f0"
app:startColor="#f00"
app:gradientRadiusWidthPercent=".5"
/>
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:text="What's up world?"/>
</FrameLayout>
0 votes
GradientRadius est une propriété qui se base sur une valeur entière. L'insertion d'un pourcentage ou de toute autre valeur de mesure ne fonctionnera pas. Je sais que ce n'est pas la réponse que vous cherchez, mais au moins cela vous aidera à préciser ce que vous recherchez.
0 votes
Même problème ici (du moins lorsque je prévisualise ma mise en page dans Eclipse) : le dégradé n'est pas appliqué si le rayon est spécifié avec
%
o%p
0 votes
Le pire, c'est que cela ne fonctionne pas, même si j'ai une ressource entière définie ailleurs, et que je m'y réfère ici (@integer/gradientRadius). Il semble qu'il n'accepte que les entiers absolus codés en dur.
1 votes
Les pourcentages ne sont pas pris en charge pour les valeurs de dimension d'Android. Cela a été clairement établi auparavant : groups.google.com/forum/#!msg/Android-developers/EZL4n2mrpds/