Android scale animation on view

2020-01-25 04:37发布

问题:

I want to use ScaleAnimation (programmatically not in xml) to change height to view from 0 to 60% of parent height. Width of view is constant and is 50px. View is empty only background color is set.

Can someone give me code for scaleAnim using ScaleAnimation from code.

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:id="@+id/layContainer
    >
<View  
    android:layout_width="50px" 
    android:layout_height="fill_parent" 
    android:id="@+id/viewContainer" 
    android:background:"#00f00"
    />

</LinearLayout>


ScaleAnimation scaleAnim = new ScaleAnimation(...);

view before and after animation .Thanks

回答1:

Here is a code snip to do exactly that.

public void scaleView(View v, float startScale, float endScale) {
    Animation anim = new ScaleAnimation(
            1f, 1f, // Start and end values for the X axis scaling
            startScale, endScale, // Start and end values for the Y axis scaling
            Animation.RELATIVE_TO_SELF, 0f, // Pivot point of X scaling
            Animation.RELATIVE_TO_SELF, 1f); // Pivot point of Y scaling
    anim.setFillAfter(true); // Needed to keep the result of the animation
    anim.setDuration(1000);
    v.startAnimation(anim);
}

The ScaleAnimation constructor used here takes 8 args, 4 related to handling the X-scale which we don't care about (1f, 1f, ... Animation.RELATIVE_TO_SELF, 0f, ...).

The other 4 args are for the Y-scaling we do care about.

startScale, endScale - In your case, you'd use 0f, 0.6f.

Animation.RELATIVE_TO_SELF, 1f - This specifies where the shrinking of the view collapses to (referred to as the pivot in the documentation). Here, we set the float value to 1f because we want the animation to start growing the bar from the bottom. If we wanted it to grow downward from the top, we'd use 0f.

Finally, and equally important, is the call to anim.setFillAfter(true). If you want the result of the animation to stick around after the animation completes, you must run this on the animator before executing the animation.

So in your case, you can do something like this:

View v = findViewById(R.id.viewContainer);
scaleView(v, 0f, .6f);


回答2:

try this code to create Scale animation without using xml

ScaleAnimation animation = new ScaleAnimation(fromXscale, toXscale, fromYscale, toYscale, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);


回答3:

In XML, this what I use for achieving the same result. May be this is more intuitive.

scale_up.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" >

<scale
    android:duration="200"
    android:fromXScale="1.0"
    android:fromYScale="0.0"
    android:pivotX="50%"
    android:pivotY="100%"
    android:toXScale="1.0"
    android:toYScale="1.0" />

</set>

scale_down.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" >

<scale
    android:duration="200"
    android:fromXScale="1.0"
    android:fromYScale="1.0"
    android:pivotX="50%"
    android:pivotY="100%"
    android:toXScale="1.0"
    android:toYScale="0.0" />

</set>

See the animation on the X axis is from 1.0 -> 1.0 which means you don't have any scaling up in that direction and stays at the full width while, on the Y axis you get 0.0 -> 1.0 scaling, as shown in the graphic in the question. Hope this helps someone.

Some might want to know the java code as we see one requested.

Place the animation files in anim folder and then load and set animation files something like.

Animation scaleDown = AnimationUtils.loadAnimation(youContext, R.anim.scale_down);
ImagView v = findViewById(R.id.your_image_view);
v.startAnimation(scaleDown);


回答4:

Use this method (No need to xml file)

If you want scale to quarter(half x,half y)

view.animate().scaleX(0.5f).scaleY(0.5f)

If you want scale and move to bottom right

view.animate().scaleX(0.5f).scaleY(0.5f)
        .translationY((view.height/4).toFloat()).translationX((view.width/4).toFloat())

If you want move to top use (-view.height/4) and for left (-view.width/4)

If you want do something after animation ends use withEndAction(Runnable runnable) function.

You can use some other property like alpha and rotation

Full code

view.animate()
      .scaleX(0.5f).scaleY(0.5f)//scale to quarter(half x,half y)
      .translationY((view.height/4).toFloat()).translationX((view.width/4).toFloat())// move to bottom / right
      .alpha(0.5f) // make it less visible
      .rotation(360f) // one round turns
      .setDuration(1000) // all take 1 seconds
      .withEndAction(new Runnable() {
           @Override
           public void run() {
              //animation ended
           }
      });


回答5:

Resize using helper methods and start-repeat-end handlers like this:

resize(
    view1,
    1.0f,
    0.0f,
    1.0f,
    0.0f,
    0.0f,
    0.0f,
    150,
    null,
    null,
    null);

  return null;
}

Helper methods:

/**
 * Resize a view.
 */
public static void resize(
  View view,
  float fromX,
  float toX,
  float fromY,
  float toY,
  float pivotX,
  float pivotY,
  int duration) {

  resize(
    view,
    fromX,
    toX,
    fromY,
    toY,
    pivotX,
    pivotY,
    duration,
    null,
    null,
    null);
}

/**
 * Resize a view with handlers.
 *
 * @param view     A view to resize.
 * @param fromX    X scale at start.
 * @param toX      X scale at end.
 * @param fromY    Y scale at start.
 * @param toY      Y scale at end.
 * @param pivotX   Rotate angle at start.
 * @param pivotY   Rotate angle at end.
 * @param duration Animation duration.
 * @param start    Actions on animation start. Otherwise NULL.
 * @param repeat   Actions on animation repeat. Otherwise NULL.
 * @param end      Actions on animation end. Otherwise NULL.
 */
public static void resize(
  View view,
  float fromX,
  float toX,
  float fromY,
  float toY,
  float pivotX,
  float pivotY,
  int duration,
  Callable start,
  Callable repeat,
  Callable end) {

  Animation animation;

  animation =
    new ScaleAnimation(
      fromX,
      toX,
      fromY,
      toY,
      Animation.RELATIVE_TO_SELF,
      pivotX,
      Animation.RELATIVE_TO_SELF,
      pivotY);

  animation.setDuration(
    duration);

  animation.setInterpolator(
    new AccelerateDecelerateInterpolator());

  animation.setFillAfter(true);

  view.startAnimation(
    animation);

  animation.setAnimationListener(new AnimationListener() {

    @Override
    public void onAnimationStart(Animation animation) {

      if (start != null) {
        try {

          start.call();

        } catch (Exception e) {
          e.printStackTrace();
        }
      }

    }

    @Override
    public void onAnimationEnd(Animation animation) {

      if (end != null) {
        try {

          end.call();

        } catch (Exception e) {
          e.printStackTrace();
        }
      }
    }

    @Override
    public void onAnimationRepeat(
      Animation animation) {

      if (repeat != null) {
        try {

          repeat.call();

        } catch (Exception e) {
          e.printStackTrace();
        }
      }  
    }
  });
}


回答6:

public void expand(final View v) {
        ScaleAnimation scaleAnimation = new ScaleAnimation(1, 1, 1, 0, 0, 0);
        scaleAnimation.setDuration(250);
        scaleAnimation.setAnimationListener(new Animation.AnimationListener() {
            @Override
            public void onAnimationStart(Animation animation) {

            }

            @Override
            public void onAnimationEnd(Animation animation) {
                v.setVisibility(View.INVISIBLE);
            }

            @Override
            public void onAnimationRepeat(Animation animation) {

            }
        });
        v.startAnimation(scaleAnimation);
    }

    public void collapse(final View v) {
        ScaleAnimation scaleAnimation = new ScaleAnimation(1, 1, 0, 1, 0, 0);
        scaleAnimation.setDuration(250);
        scaleAnimation.setAnimationListener(new Animation.AnimationListener() {
            @Override
            public void onAnimationStart(Animation animation) {

            }

            @Override
            public void onAnimationEnd(Animation animation) {
                v.setVisibility(View.VISIBLE);
            }

            @Override
            public void onAnimationRepeat(Animation animation) {

            }
        });
        v.startAnimation(scaleAnimation);
    }