【发布时间】:2019-12-01 10:44:42
【问题描述】:
【问题讨论】:
-
@AjitSingh,那篇文章描述了标准动画(旋转、平移等)。我在这里问的是自定义动画。
【问题讨论】:
创建自定义动画最灵活(也很简单)的方法是扩展Animation 类。
一般:
setDuration() 方法设置动画的持续时间。setInterpolator() 为您的动画设置插值器(例如,您可以使用LinearInterpolator 或AccelerateInterpolator 等)applyTransformation 方法。在这里,我们对 interpolatedTime 变量感兴趣,它在 0.0 和 1.0 之间变化,代表您的动画进度。这是一个例子(我正在使用这个类来改变我的Bitmap的sset。Bitmap本身是在draw方法中绘制的):
public class SlideAnimation extends Animation {
private static final float SPEED = 0.5f;
private float mStart;
private float mEnd;
public SlideAnimation(float fromX, float toX) {
mStart = fromX;
mEnd = toX;
setInterpolator(new LinearInterpolator());
float duration = Math.abs(mEnd - mStart) / SPEED;
setDuration((long) duration);
}
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
super.applyTransformation(interpolatedTime, t);
float offset = (mEnd - mStart) * interpolatedTime + mStart;
mOffset = (int) offset;
postInvalidate();
}
}
您也可以使用Transformation#getMatrix()修改View。
更新
如果您使用的是 Android Animator 框架(或兼容性实现 - NineOldAndroids),您只需为您的自定义 View 属性声明 setter 和 getter 并直接对其进行动画处理。这是另一个例子:
public class MyView extends View {
private int propertyName = 50;
/* your code */
public int getPropertyName() {
return propertyName;
}
public void setPropertyName(int propertyName) {
this.propertyName = propertyName;
}
/*
There is no need to declare method for your animation, you
can, of course, freely do it outside of this class. I'm including code
here just for simplicity of answer.
*/
public void animateProperty() {
ObjectAnimator.ofInt(this, "propertyName", 123).start();
}
}
【讨论】:
Animation animation = new AnimationDrawable();
animation.addFrame(getResources().getDrawable(R.drawable.exp1), 50);
animation.addFrame(getResources().getDrawable(R.drawable.exp2), 50);
animation.addFrame(getResources().getDrawable(R.drawable.exp3), 50);
animation.addFrame(getResources().getDrawable(R.drawable.exp4), 50);
animation.addFrame(getResources().getDrawable(R.drawable.exp5), 50);
animation.addFrame(getResources().getDrawable(R.drawable.exp6), 50);
这是我用来在 onCreate() 中生成自定义的逐帧动画的代码。
之后我需要启动动画,但必须在 UI 线程中启动。因此我使用了 Runnable。
class Starter implements Runnable {
public void run() {
animation.stop();
animation.start();
}
}
我使用 ImageView 的 .post() 方法从 onClick() 启动 Runnable:
((ImageView) findViewById(R.id.ImageToAnimateOnClicking)).post(new Starter());
【讨论】:
我假设您将每个帧创建为位图,然后将其直接传递给动画,而不是从资源中获取 Drawable。
Bitmap bm = Bitmap.createBitmap(width,height,Bitmap.Config.ARGB_888);
Canvas c = new Canvas(bm);
.... Draw to bitmap
animation.addFrame(bm,50)
.... repeat for all frames you wish to add.
【讨论】:
用另一个 Fragment 替换 Fragment 时的自定义动画:
getSupportFragmentManager().beginTransaction()
.setCustomAnimations(R.anim.slide_in_right, R.anim.slide_out_left)
.replace(currentFragment.getId(), newFragment).commit();
currentFragment = newFragment;
XML slide_in_right:
<translate android:fromXDelta="100%p" android:toXDelta="0"
android:duration="1000"/>
XML slide_out_left:
<translate android:fromXDelta="0" android:toXDelta="-100%p"
android:duration="1000"/>
【讨论】:
您可以将四种类型的动画添加到自定义视图中。
这是一个blog post,它详细解释了它们中的每一个。
创建动画后,只需使用以下代码将该自定义动画添加到视图。
findById(R.id.element).startAnimation(AnimationUtils.loadAnimation(this, R.anim.custom_animation));
【讨论】:
除了在 XML 中定义补间动画之外,您还可以定义逐帧动画(存储在 res/drawable 中)。
<animation-list
xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot="true"
>
<item android:drawable="@drawable/frame1" android:duration="300" />
<item android:drawable="@drawable/frame2" android:duration="300" />
<item android:drawable="@drawable/frame3" android:duration="300" />
</animation-list>
通过 setBackgroundResource 将动画设置为 View 背景。
如果您想做一些更复杂的事情,请查看Canvas 类。请参阅有关如何draw with Canvas 的简要介绍。
【讨论】: