我正在尝试使用XML Animations将视图从0%缩放到150%(比“实际尺寸”大50%)。然后将尺寸从150%缩小到100%的“实际尺寸”。意图是有点“反弹”效果,其中视图将从无到有扩大到应有的大小,然后“反弹”或“捕捉”到适当的大小。
这里是说明我想完成的时间表的图像。
我正在使用此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%。
我已经尝试过可以在每个比例动画和布景本身上想到的fillBefore
,fillAfter
和fillEnabled
的每种组合,但是到目前为止,我一直找不到这些设置的组合这将使其表现出预期的效果。
[我发现This Article似乎与我的情况有关,这促使我测试了fill
属性的更多组合。但是到目前为止,我仍然无法获得我希望的结果。
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);
}
}
}