Применение последовательных анимаций к ImageView в Android
Вопрос
Я хотел бы применить последовательные анимации (скажем, ScaleAnimation) к ImageView, показывающему изображение ресурса.Анимация запускается кнопкой.Например, я хотел бы постепенно увеличивать изображение при каждом нажатии кнопки.
Я установил fillAfter="true" для анимации.Однако все анимации начинаются с исходного состояния ImageView.Кажется, что ImageView сбрасывает свое состояние, и анимация всегда одинакова, а не начинается с конечного состояния предыдущей анимации.
Что я делаю не так?
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button button = (Button)findViewById(R.id.Button01);
button.setOnClickListener(new OnClickListener() {
public void onClick(View arg0) {
animate();
}});
}
private void animate() {
ImageView imageView = (ImageView) findViewById(R.id.ImageView01);
ScaleAnimation scale = new ScaleAnimation((float)1.0, (float)1.5, (float)1.0, (float)1.5);
scale.setFillAfter(true);
scale.setDuration(500);
imageView.startAnimation(scale);
}
Решение
Кажется, что ImageView сбрасывает свое состояние, а анимация всегда одинакова, вместо того, чтобы начинать с окончательного состояния предыдущей анимации.
Именно так!Я уверен, что есть применение fillAfter="true"
, но я еще не понял смысла этого.
Что вам нужно сделать, это настроить AnimationListener
на каждого Animation
значимости и сделать что-то, что понравится слушателю onAnimationEnd()
чтобы фактически сохранить конечное состояние вашей анимации.я не играл с ScaleAnimation
поэтому я не совсем уверен, каким будет способ «сохранить конечное состояние».Если бы это было AlphaAnimation
, идя от 1.0
к 0.0
, ты бы сделал виджет INVISIBLE
или GONE
в onAnimationEnd()
, например.
Другие советы
У меня была та же проблема, и я создал следующий код, чтобы легко использовать различные анимации.На данный момент он поддерживает только перевод и альфа-уровни, поскольку я не использовал масштабирование, но его можно легко расширить для поддержки большего количества функций.
Я сбросил прокрутку и видимость перед запуском анимации, но это только потому, что мне нужно было включать/выключать анимацию.
И логическое значение «doEnd» предназначено для того, чтобы избежать переполнения стека при рекурсии (по какой-то непонятной причине scrollTo вызывает onAnimationEnd...)
private void setViewPos(View view, Animation anim, long time){
// Get the transformation
Transformation trans = new Transformation();
anim.getTransformation(time, trans);
// Get the matrix values
float[] values = new float[9];
Matrix m = trans.getMatrix();
m.getValues(values);
// Get the position and apply the scroll
final float x = values[Matrix.MTRANS_X];
final float y = values[Matrix.MTRANS_Y];
view.scrollTo(-(int)x, -(int)y);
// Show/hide depending on final alpha level
if (trans.getAlpha() > 0.5){
view.setVisibility(VISIBLE);
} else {
view.setVisibility(INVISIBLE);
}
}
private void applyAnimation(final View view, final Animation anim){
view.scrollTo(0, 0);
view.setVisibility(VISIBLE);
anim.setAnimationListener(new AnimationListener(){
private boolean doEnd = true;
@Override
public void onAnimationEnd(Animation animation) {
if (doEnd){
doEnd = false;
setViewPos(view, animation, anim.getStartTime() + anim.getDuration());
}
}
@Override
public void onAnimationRepeat(Animation animation) {
}
@Override
public void onAnimationStart(Animation animation) {
}
});
view.startAnimation(anim);
}