具有较小“反弹力”的缩放动画

问题描述 投票:0回答:1

我正在尝试使用XML Animations将视图从0%缩放到150%(比“实际尺寸”大50%)。然后将尺寸从150%缩小到100%的“实际尺寸”。意图是有点“反弹”效果,其中视图将从无到有扩大到应有的大小,然后“反弹”或“捕捉”到适当的大小。

这里是说明我想完成的时间表的图像。

Timeline of desired Animations

我正在使用此XML动画代码:

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    >
    <scale android:fromXScale="0"
        android:fromYScale="0"
        android:toXScale="1.5"
        android:toYScale="1.5"
        android:duration="200"
        android:pivotX="50%"
        android:pivotY="100%"
        android:fillAfter="false"
        />
    <scale android:fromXScale="1.5"
        android:fromYScale="1.5"
        android:toXScale="1.0"
        android:toYScale="1.0"
        android:duration="100"
        android:pivotX="50%"
        android:pivotY="100%"
        android:startOffset="200"
        />
</set>

我遇到的问题是,在第一个比例动画完成后,视图正确地以150%的大小显示,但是当它运行第二个动画时,它相对于我们在第一个比例动画中以(150% )作为“实际尺寸” 100%,即1.0。

因此,当第二个动画运行时,而不是我的视图从150%缩小到实际大小的100%时,实际上是从150%的150%(225%)缩小到150%。这意味着在动画结束时,视图仍然太大,在我的情况下,其大小仅为实际大小的150%。

是否有某种方法可以指示第二个Animation或Animation集忽略第一个动画的结束值,而只是使用视图的“真实”大小,以便从字面上理解该代码并将其从150缩放实际尺寸的百分比降低到实际尺寸的100%。

我已经尝试过可以在每个比例动画和布景本身上想到的fillBeforefillAfterfillEnabled的每种组合,但是到目前为止,我一直找不到这些设置的组合这将使其表现出预期的效果。

[我发现This Article似乎与我的情况有关,这促使我测试了fill属性的更多组合。但是到目前为止,我仍然无法获得我希望的结果。

android animation layout scale android-view
1个回答
0
投票

Facebook有一个名为Rebound的Java库,该库可以模拟弹簧动力学并添加现实世界的物理学。示例代码:

import com.facebook.rebound.BaseSpringSystem;
import com.facebook.rebound.SimpleSpringListener;
import com.facebook.rebound.Spring;
import com.facebook.rebound.SpringSystem;
import com.facebook.rebound.SpringUtil;

/**
 * This Activity presents an ImageView that scales down when pressed and returns to full size when
 * released. This demonstrates a very simple integrates a very Simple integration of a Rebound
 * Spring model to drive a bouncy animation as the photo scales up and down. You can control the
 * Spring configuration by tapping on the blue nub at the bottom of the screen to reveal the
 * SpringConfiguratorView. From this view you can adjust the tension and friction of the animation
 * spring and observe the effect these values have on the animation.
 */
public class MainActivity extends Activity {

  private final BaseSpringSystem mSpringSystem = SpringSystem.create();
  private final ExampleSpringListener mSpringListener = new ExampleSpringListener();
  private FrameLayout mRootView;
  private Spring mScaleSpring;
  private View mImageView;

  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.main);
    mRootView = (FrameLayout) findViewById(R.id.root_view);
    mImageView = mRootView.findViewById(R.id.image_view);

    // Create the animation spring.
    mScaleSpring = mSpringSystem.createSpring();

    // Add an OnTouchListener to the root view.
    mRootView.setOnTouchListener(new View.OnTouchListener() {
      @Override
      public boolean onTouch(View v, MotionEvent event) {
        switch (event.getAction()) {
          case MotionEvent.ACTION_DOWN:
            // When pressed start solving the spring to 1.
            mScaleSpring.setEndValue(1);
            break;
          case MotionEvent.ACTION_UP:
          case MotionEvent.ACTION_CANCEL:
            // When released start solving the spring to 0.
            mScaleSpring.setEndValue(0);
            break;
        }
        return true;
      }
    });
  }

  @Override
  public void onResume() {
    super.onResume();
    // Add a listener to the spring when the Activity resumes.
    mScaleSpring.addListener(mSpringListener);
  }

  @Override
  public void onPause() {
    super.onPause();
    // Remove the listener to the spring when the Activity pauses.
    mScaleSpring.removeListener(mSpringListener);
  }

  private class ExampleSpringListener extends SimpleSpringListener {
    @Override
    public void onSpringUpdate(Spring spring) {
      // On each update of the spring value, we adjust the scale of the image view to match the
      // springs new value. We use the SpringUtil linear interpolation function mapValueFromRangeToRange
      // to translate the spring's 0 to 1 scale to a 100% to 50% scale range and apply that to the View
      // with setScaleX/Y. Note that rendering is an implementation detail of the application and not
      // Rebound itself. If you need Gingerbread compatibility consider using NineOldAndroids to update
      // your view properties in a backwards compatible manner.
      float mappedValue = (float) SpringUtil.mapValueFromRangeToRange(spring.getCurrentValue(), 0, 1, 1, 0.5);
      mImageView.setScaleX(mappedValue);
      mImageView.setScaleY(mappedValue);
    }
  }

}
© www.soinside.com 2019 - 2024. All rights reserved.