Come animare il gradiente dal colore n. 1 al colore n. 2? Qualcosa di simile aCome animare il gradiente?
ho intenzione di usarlo come la salute-bar per unità (animazione in modo, sarà finit partendo con il verde e termina con rosso)
Come animare il gradiente dal colore n. 1 al colore n. 2? Qualcosa di simile aCome animare il gradiente?
ho intenzione di usarlo come la salute-bar per unità (animazione in modo, sarà finit partendo con il verde e termina con rosso)
Mentre googling, io trovato 2 modi per farlo per Android: use ShaderFactory o estende View, utilizzando new Shader(new LinearGradient())
. Entrambe le risposte fanno lo stesso - chiamando lo new Shader()
ogni chiamata del metodo View.onDraw(Canvas canvas)
. È davvero costoso se il numero di tali gradienti animati è superiore a ~ 3.
Quindi l'ho fatto in un altro modo. Ho evitato di chiamare new
ogni onDraw()
, utilizzando il singolo valore predefinito LinearGradient
. Ecco come è assomigliare (gif, così animazione decaduto):
Il trucco è quello di creare LinearGradient
che è colorsCount
volte più grande di View.getWidth()
. Successivamente è possibile utilizzare canvas.translate()
, mentre si disegna il gradiente, per cambiarne il colore, quindi nessuna chiamata new
in onDraw()
.
Per creare una sfumatura, è necessario larghezza e altezza attuali. L'ho fatto in onSizeChanged()
. Anche io ho impostato Shader
anche qui.
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
width = getWidth();
height = getHeight();
LinearGradient gradient = new LinearGradient(
0, height/2, width * colors.length - 1, height/2,
colors, null, Shader.TileMode.REPEAT);
fillPaint.setShader(gradient);
shapePath = getParallelogrammPath(width, height, sidesGap);
shapeBorderPath = getParallelogrammPath(width, height, sidesGap);
}
Uso il percorso a causa delle viste di parallelogrammi, è possibile utilizzare qualsiasi cosa si desideri. Nell'attuare disegno, si dovrebbe notare 2 cose: è necessario translate()
intero canvas
su offset di corrente e offset()
la forma di riempimento:
@Override
protected void onDraw(Canvas canvas) {
canvas.save();
canvas.translate(-gradientOffset, 0);
shapePath.offset(gradientOffset, 0f, tempPath);
canvas.drawPath(tempPath, fillPaint);
canvas.restore();
canvas.drawPath(shapeBorderPath, borderPaint);
super.onDraw(canvas); // my View is FrameLayout, so need to call it after
}
Inoltre si dovrebbe utilizzare canvas.save()
& canvas.restore()
. Salva la matrice interna della tela per impilarla e ripristinarla in modo corrispondente.
Quindi l'ultimo cosa che devi fare è animare gradientOffset
. Puoi utilizzare tutto ciò che desideri come ObjectAnimator (Property Animation). Ho usato TimeAnimator, perché avevo bisogno di controllare updateTick
e iniziare lo spostamento direttamente. Qui è la mia realizzazione (un po 'difficile e dura):
static public final int LIFETIME_DEAFULT = 2300;
private long lifetime = LIFETIME_DEAFULT, updateTickMs = 25, timeElapsed = 0;
private long accumulatorMs = 0;
private float gradientOffset = 0f;
public void startGradientAnimation() {
stopGradientAnimation();
resolveTimeElapsed();
final float gradientOffsetCoef = (float) (updateTickMs)/lifetime;
final int colorsCount = this.colors.length - 1;
gradientAnimation.setTimeListener(new TimeAnimator.TimeListener() {
@Override
public void onTimeUpdate(TimeAnimator animation, long totalTime, long deltaTime) {
final long gradientWidth = width * colorsCount;
if (totalTime > (lifetime - timeElapsed)) {
animation.cancel();
gradientOffset = gradientWidth;
invalidate();
} else {
accumulatorMs += deltaTime;
final long gradientOffsetsCount = accumulatorMs/updateTickMs;
gradientOffset += (gradientOffsetsCount * gradientWidth) * gradientOffsetCoef;
accumulatorMs %= updateTickMs;
boolean gradientOffsetChanged = (gradientOffsetsCount > 0) ? true : false;
if (gradientOffsetChanged) {
invalidate();
}
}
}
});
gradientAnimation.start();
}
Il codice completo View
è possibile trovare here
Non capisco ... lei ha chiesto la domanda e ha risposto allo stesso tempo su lo stesso giorno? Questa non è mai stata una domanda. –
@ Chris-Jr, ho cercato molto e non ho trovato una risposta che volevo. Così ho fatto una sorta di ricerca e finalmente l'ho preso. Poi ho pensato "hm, forse qualcun altro lo cercherà in futuro e resterà bloccato come faccio io?" - Così ho creato la domanda con la risposta. Inoltre, c'è una funzione integrata per farlo. Prova a fare clic su 'Ask Question'. C'è un assegno 'Rispondi alla tua stessa domanda - condividi le tue conoscenze, stile Q & A' – Nexen
Ah, va bene, sono stato solo confuso dai tempi. Grazie per questo, e grazie per aver condiviso la tua soluzione. –