编辑:现在完美运行!- 在第一次重复后插入动画侦听器调用 setStartOffset() 回到 0,这样它就不会保持随机“跳跃”。
我为这个问题找到了一个可行的解决方案,它通过将动画定时到当前系统毫秒来工作。这有点像 hack,因为它使用反射来获取mAnimation
. ProgressBar
话虽如此,该字段自创建以来一直保留在 Android 源代码中(最高工作于 4.2)。
创建android.widget.SyncedProgressBar
类,并使用它而不是ProgressBar
在您的 .xml 文件中。它实质上使动画在动画持续时间的开始处开始。您还可以setDuration(500)
尝试验证它是否有效(进度轮会很快旋转)。希望这可以帮助!
package android.widget;
import android.annotation.SuppressLint;
import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.view.animation.Animation.AnimationListener;
import java.lang.reflect.Field;
/**
* @author Oleg Vaskevich
*
*/
public class SyncedProgressBar extends ProgressBar {
public SyncedProgressBar(Context context) {
super(context);
modifyAnimation();
}
public SyncedProgressBar(Context context, AttributeSet attrs) {
super(context, attrs);
modifyAnimation();
}
public SyncedProgressBar(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
modifyAnimation();
}
@Override
public void setVisibility(int v) {
super.setVisibility(v);
modifyAnimation();
}
@SuppressLint("NewApi")
@Override
protected void onVisibilityChanged(View changedView, int visibility) {
super.onVisibilityChanged(changedView, visibility);
modifyAnimation();
}
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
modifyAnimation();
}
@Override
public synchronized void setIndeterminate(boolean indeterminate) {
super.setIndeterminate(indeterminate);
modifyAnimation();
}
public void modifyAnimation() {
Field mAnim;
try {
mAnim = ProgressBar.class.getDeclaredField("mAnimation");
mAnim.setAccessible(true);
AlphaAnimation anim = (AlphaAnimation) mAnim.get(this);
if (anim == null)
return;
// set offset to that animations start at same time
long duration = anim.getDuration();
long timeOffset = System.currentTimeMillis() % duration;
anim.setDuration(duration);
anim.setStartOffset(-timeOffset);
anim.setAnimationListener(new AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
}
@Override
public void onAnimationRepeat(Animation animation) {
animation.setStartOffset(0);
}
@Override
public void onAnimationEnd(Animation animation) {
}
});
} catch (Exception e) {
Log.d("SPB", "that didn't work out...", e);
return;
}
postInvalidate();
}
}