ObjectAnimator 重置为初始状态
ObjectAnimator reset to initial status
我想达到的目标
- 自定义视图最初是绿色的。
- 单击按钮时,视图开始在绿色和白色之间无限地设置其颜色动画。
- 再次单击按钮时,视图应将其颜色重置为其初始状态(绿色)并停止动画。
第 2 步和第 3 步可以无限次应用。
问题
我的问题是,当动画进行时单击按钮时,视图不会将其颜色重置为初始状态(绿色),而是无论动画到达那一刻的哪个点,视图变为最终状态(白色)。
我曾尝试使用 SO 上另一个类似问题的 solution,但没有成功。
代码
我如何初始化 ObjectAnimator
animator = ObjectAnimator.ofArgb(this, "color", WHITE);
animator.setDuration(ANIMATION_DURATION);
animator.setRepeatCount(Animation.INFINITE);
animator.setRepeatMode(ValueAnimator.REVERSE);
自定义视图 class 有一个实现 onAnimationEnd()
的私有成员 Animator.AnimatorListener
,我将它附加到 startAnimation()
中的动画器,将它从onAnimationEnd()
中的动画师,因为我上面引用的解决方案是这样说的。
private Animator.AnimatorListener animatorListener = new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
animation.removeListener(this);
animation.setDuration(0);
((ObjectAnimator) animation).reverse();
}
};
public void startAnimation(){
animator.addListener(animatorListener);
animator.setDuration(ANIMATION_DURATION);
animator.start();
}
public void stopAnimation(){
animator.end();
// animatorListener.onAnimationEnd() will be called here
}
我不确定这是否是实现我目标的最佳方式,如有任何建议,我们将不胜感激。
尝试以下操作:
public class Demo8 extends AppCompatActivity {
private Button b;
private ViewC v;
private ObjectAnimator animator;
private enum animation_state {START, CLEAR}
private animation_state animation_current_state = animation_state.START;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.demo8);
b = (Button) findViewById(R.id.b);
v = (ViewC) findViewById(R.id.v);
b.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (!animator.isRunning()) {
CAnimator(animation_state.START);
} else {
CAnimator(animation_state.CLEAR);
}
}
});
animator = ObjectAnimator.ofArgb(v, "background", Color.WHITE);
animator.setDuration(1000);
animator.setRepeatCount(Animation.INFINITE);
animator.setRepeatMode(ObjectAnimator.REVERSE);
animator.addListener(animatorListener);
}
private Animator.AnimatorListener animatorListener = new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animation, boolean isReverse) {
}
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
Log.e("End" , "***********True");
animation.removeListener(this);
}
@Override
public void onAnimationRepeat(Animator animation) {
super.onAnimationRepeat(animation);
Log.e("Repeat" , "***********True");
}
};
private void CAnimator(animation_state s) {
animation_current_state = s;
if (s == animation_state.START) {
animator.start();
} else if (s == animation_state.CLEAR) {
animator.cancel();
v.setBackground(Color.GREEN);
}
}
}
ViewC(自定义视图):
public class ViewC extends View {
private static final Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
private int color;
public ViewC(Context context) {
super(context);
}
public ViewC(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
color = Color.GREEN;
}
public ViewC(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public ViewC(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
final RectF rect = new RectF(2.5f * 20,
0.5f * (getHeight() - 5), getWidth() - 2.5f * 20,
0.5f * (getHeight() + 5));
paint.setColor(color);
canvas.drawRect(rect, paint);
}
public void setBackground(int color){
this.color = color;
invalidate();
}
}
布局demo8.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical">
<com.example.admin.machinelearning.ViewC // Change this to your package
android:layout_width="match_parent"
android:layout_height="50dp"
android:id="@+id/v">
</com.example.admin.machinelearning.ViewC>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/b"
android:text="Button"/>
</LinearLayout>
我想达到的目标
- 自定义视图最初是绿色的。
- 单击按钮时,视图开始在绿色和白色之间无限地设置其颜色动画。
- 再次单击按钮时,视图应将其颜色重置为其初始状态(绿色)并停止动画。
第 2 步和第 3 步可以无限次应用。
问题
我的问题是,当动画进行时单击按钮时,视图不会将其颜色重置为初始状态(绿色),而是无论动画到达那一刻的哪个点,视图变为最终状态(白色)。
我曾尝试使用 SO 上另一个类似问题的 solution,但没有成功。
代码
我如何初始化 ObjectAnimator
animator = ObjectAnimator.ofArgb(this, "color", WHITE);
animator.setDuration(ANIMATION_DURATION);
animator.setRepeatCount(Animation.INFINITE);
animator.setRepeatMode(ValueAnimator.REVERSE);
自定义视图 class 有一个实现 onAnimationEnd()
的私有成员 Animator.AnimatorListener
,我将它附加到 startAnimation()
中的动画器,将它从onAnimationEnd()
中的动画师,因为我上面引用的解决方案是这样说的。
private Animator.AnimatorListener animatorListener = new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
animation.removeListener(this);
animation.setDuration(0);
((ObjectAnimator) animation).reverse();
}
};
public void startAnimation(){
animator.addListener(animatorListener);
animator.setDuration(ANIMATION_DURATION);
animator.start();
}
public void stopAnimation(){
animator.end();
// animatorListener.onAnimationEnd() will be called here
}
我不确定这是否是实现我目标的最佳方式,如有任何建议,我们将不胜感激。
尝试以下操作:
public class Demo8 extends AppCompatActivity {
private Button b;
private ViewC v;
private ObjectAnimator animator;
private enum animation_state {START, CLEAR}
private animation_state animation_current_state = animation_state.START;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.demo8);
b = (Button) findViewById(R.id.b);
v = (ViewC) findViewById(R.id.v);
b.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (!animator.isRunning()) {
CAnimator(animation_state.START);
} else {
CAnimator(animation_state.CLEAR);
}
}
});
animator = ObjectAnimator.ofArgb(v, "background", Color.WHITE);
animator.setDuration(1000);
animator.setRepeatCount(Animation.INFINITE);
animator.setRepeatMode(ObjectAnimator.REVERSE);
animator.addListener(animatorListener);
}
private Animator.AnimatorListener animatorListener = new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animation, boolean isReverse) {
}
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
Log.e("End" , "***********True");
animation.removeListener(this);
}
@Override
public void onAnimationRepeat(Animator animation) {
super.onAnimationRepeat(animation);
Log.e("Repeat" , "***********True");
}
};
private void CAnimator(animation_state s) {
animation_current_state = s;
if (s == animation_state.START) {
animator.start();
} else if (s == animation_state.CLEAR) {
animator.cancel();
v.setBackground(Color.GREEN);
}
}
}
ViewC(自定义视图):
public class ViewC extends View {
private static final Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
private int color;
public ViewC(Context context) {
super(context);
}
public ViewC(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
color = Color.GREEN;
}
public ViewC(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public ViewC(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
final RectF rect = new RectF(2.5f * 20,
0.5f * (getHeight() - 5), getWidth() - 2.5f * 20,
0.5f * (getHeight() + 5));
paint.setColor(color);
canvas.drawRect(rect, paint);
}
public void setBackground(int color){
this.color = color;
invalidate();
}
}
布局demo8.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical">
<com.example.admin.machinelearning.ViewC // Change this to your package
android:layout_width="match_parent"
android:layout_height="50dp"
android:id="@+id/v">
</com.example.admin.machinelearning.ViewC>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/b"
android:text="Button"/>
</LinearLayout>