Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

LinearGradient Center Animation

I want to animate the center of a linear gradient, so that at the beginning the whole drawable is color1 and at the end the whole drawable is color2 and in between the center of the gradient moves from left to right.

GradientDrawable gd = new GradientDrawable(
                              GradientDrawable.Orientation.LEFT_RIGHT,
                              new int[] {color1, color2});
gd.setCornerRadius(0f);
gd.setGradientCenter(x, 0);
view.setBackgroundDrawable(gd);

The problem is that setGradientCenter doesn't make any difference. According to this answer https://stackoverflow.com/a/14383974/1395697 there is an issue with setGradientCenter() but the solution in this answer doesn't work for me because I change the gradient in onTouch() when the user swipes his finger over the view, so it needs to be really fast.

Is there a way to do this?

I want to do something like this (all the touch stuff works great but not the animated gradient):

enter image description here

like image 775
DominicM Avatar asked Jan 28 '14 10:01

DominicM


1 Answers

What you ask for isn't a pure linear gradient - a linear gradient between two colors on a fixed width has only one math function defining it and that's why you can't change the center. What I think you are looking for is a fixed color beginning and end, and a linear gradient area between them.

Try this solution:

    sf = new ShapeDrawable.ShaderFactory() {
     @Override
     public Shader resize(int width, int height) {
        LinearGradient lg = new LinearGradient(0, 0, view.getWidth(), 0, new int[] {Color.WHITE, Color.BLACK}, //substitute the correct colors for these
                 new float[] {center - 0.3f, center + 0.3f}, Shader.TileMode.REPEAT);
        return lg;
     }
  };
  p = new PaintDrawable();
  rectShape = new RectShape();
  p.setShape(rectShape);
  p.setShaderFactory(sf);
  view.setBackgroundDrawable((Drawable) p);
  view.setOnTouchListener(new View.OnTouchListener() {

     @Override
     public boolean onTouch(View v, MotionEvent event) {
        center = event.getX() / view.getWidth(); // calculate the center
        p.setShape(rectShape); // this makes the shader recreate the lineargradient
        return true;
     }
  });

This code seems to reacts fast enough to touch, but does create multiple instances of LinearGradient.

like image 97
Raanan Avatar answered Oct 07 '22 21:10

Raanan