android – 如何动画渐变?

前端之家收集整理的这篇文章主要介绍了android – 如何动画渐变?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
如何设置从颜色#1到颜色#2的渐变动画?类似的东西

我打算将它用作单位的健康栏(因此,它将是以绿色开始并以红色结束的有限动画)

解决方法

在谷歌搜索时,我找到了两种方法来为android: use ShaderFactory或扩展View,使用新的Shader(新的LinearGradient()).两个答案都是一样的 – 每次调用View.onDraw(Canvas canvas)方法调用新的Shader().如果这样的动画渐变数量超过~3,它真的很贵.

所以我采取了另一种方式.我使用单个预先计算的LinearGradient避免使用onDraw()调用new.这就是它的样子(gif,所以动画衰败):

诀窍是创建LinearGradient,它的colorsCount大于View.getWidth().之后,您可以使用canvas.translate(),同时绘制渐变,以更改其颜色,因此onDraw()中根本没有新的调用.

要创建渐变,您需要当前的宽度和高度.我是在onSizeChanged()中完成的.我也在这里设置了Shader.

  1. @Override
  2. protected void onSizeChanged(int w,int h,int oldw,int oldh) {
  3. super.onSizeChanged(w,h,oldw,oldh);
  4.  
  5. width = getWidth();
  6. height = getHeight();
  7.  
  8. LinearGradient gradient = new LinearGradient(
  9. 0,height / 2,width * colors.length - 1,colors,null,Shader.TileMode.REPEAT);
  10. fillPaint.setShader(gradient);
  11.  
  12. shapePath = getParallelogrammPath(width,height,sidesGap);
  13. shapeBorderPath = getParallelogrammPath(width,sidesGap);
  14. }

我使用路径因为平行四边形视图,你可以使用你想要的任何东西.在实现绘图时,您应该注意两件事:您需要在当前偏移量上翻译()整个画布,并在填充形状上使用offset():

  1. @Override
  2. protected void onDraw(Canvas canvas) {
  3. canvas.save();
  4. canvas.translate(-gradientOffset,0);
  5. shapePath.offset(gradientOffset,0f,tempPath);
  6. canvas.drawPath(tempPath,fillPaint);
  7. canvas.restore();
  8.  
  9. canvas.drawPath(shapeBorderPath,borderPaint);
  10.  
  11. super.onDraw(canvas); // my View is FrameLayout,so need to call it after
  12. }

你也应该使用canvas.save()& canvas.restore().它会将canvas的内部矩阵保存到堆栈中并相应地恢复它.

所以你需要做的最后一件事是为gradientOffset设置动画.你可以使用你想要的一切,如ObjectAnimator (Property Animation).我使用TimeAnimator,因为我需要控制updateTick并直接开始偏移.这是我的认识(有点困难和苛刻):

  1. static public final int LIFETIME_DEAFULT = 2300;
  2. private long lifetime = LIFETIME_DEAFULT,updateTickMs = 25,timeElapsed = 0;
  3. private long accumulatorMs = 0;
  4. private float gradientOffset = 0f;
  5.  
  6. public void startGradientAnimation() {
  7. stopGradientAnimation();
  8. resolveTimeElapsed();
  9.  
  10. final float gradientOffsetCoef = (float) (updateTickMs) / lifetime;
  11. final int colorsCount = this.colors.length - 1;
  12. gradientAnimation.setTimeListener(new TimeAnimator.TimeListener() {
  13. @Override
  14. public void onTimeUpdate(TimeAnimator animation,long totalTime,long deltaTime) {
  15. final long gradientWidth = width * colorsCount;
  16. if (totalTime > (lifetime - timeElapsed)) {
  17. animation.cancel();
  18. gradientOffset = gradientWidth;
  19. invalidate();
  20. } else {
  21. accumulatorMs += deltaTime;
  22.  
  23. final long gradientOffsetsCount = accumulatorMs / updateTickMs;
  24. gradientOffset += (gradientOffsetsCount * gradientWidth) * gradientOffsetCoef;
  25. accumulatorMs %= updateTickMs;
  26.  
  27. boolean gradientOffsetChanged = (gradientOffsetsCount > 0) ? true : false;
  28. if (gradientOffsetChanged) {
  29. invalidate();
  30. }
  31. }
  32. }
  33. });
  34.  
  35. gradientAnimation.start();
  36. }

您可以找到完整的View代码here

猜你在找的Android相关文章