Мне удалось разделить один экземпляр Animation между несколькими представлениями. По крайней мере, с AlphaAnimation. У меня был ListView и анимация, которая должна применяться к конкретному дочернему элементу всех представлений элементов списка. В моем случае, должно быть возможным, чтобы представления могли «присоединиться» и «покинуть» общую анимацию в любое время, и это никоим образом не должно влиять на другие анимированные виды или мешать уже запущенной анимации.
Чтобы добиться этого, мне пришлось сделать скорректированную копию Android AlphaAnimation.
Мой вариант использования довольно особенный, но пусть он будет здесь только на тот случай, если кому-то придется столкнуться с аналогичной целью с ListView.
/**
* This class is a copy of android's stock AlphaAnimation with two adjustments:
* - fromAlpha, toAlpha and duration are settable at any time.
* - reset() method can be blocked. Reason: view.setAnimation() calls animation's reset() method
* which is not intended in our use case.
* For every new list item view we call setAnimation once for it's life time
* and animation should not be reset because it is shared by all list item views and may be in progress.
*/
public class MutableAlphaAnimation extends Animation {
private float mFromAlpha;
private float mToAlpha;
private boolean resetBlocked;
public MutableAlphaAnimation() {
}
public void start(float fromAlpha, float toAlpha, long duration) {
mFromAlpha = fromAlpha;
mToAlpha = toAlpha;
setDuration(duration);
setStartTime(START_ON_FIRST_FRAME);
}
public void setResetBlocked(boolean resetBlocked) {
this.resetBlocked = resetBlocked;
}
@Override
public void reset() {
if (! resetBlocked) super.reset();
}
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
final float alpha = mFromAlpha;
t.setAlpha(alpha + ((mToAlpha - alpha) * interpolatedTime));
}
@Override
public boolean willChangeTransformationMatrix() {
return false;
}
@Override
public boolean willChangeBounds() {
return false;
}
}
Чтобы установить анимацию для вида:
animation.setResetBlocked(true);
view.setAnimation(animation);
animation.setResetBlocked(false);
И чтобы запустить анимацию (предварительно установленную setAnimation), нужно сделать ДВА:
animation.start(0.0f, 1.0f, FADE_IN_DURATION);
И после этого вы должны вручную вызывать invalidate () для каждого представления, на которое влияет анимация.
Обычная функция startAnimation () делает тебя недействительной (), а setAnimation - нет.
(читайте комментарий о методе View.setAnimation () в источниках Android).