I made "heart beat effect button"(Continuous blinking) using ObjectAnimator, And it works fine.
There is 4 buttons, named btn1RT, btn2LT, btn3LB and btn4RB. If one of the button starts blinking, other buttons will be disappeared.
Question: I refactored this code, and it does not working anymore. I can't stop buttons from blinking, so all of my buttons are blinking. I want to know why these buttons cannot be stopped.
I think passing ObjectAnimator as a parameter is problem, but there is no clue.
Any help will be appreciated.
Before:
private void start1HeartBeat() {
oa1 = ObjectAnimator.ofFloat(btn1RT, "alpha", 1, 0);
oa1.setDuration(HEARTBEAT_RUN_DURATION);
oa1.setRepeatCount(ValueAnimator.INFINITE);
oa1.setRepeatMode(ValueAnimator.REVERSE);
oa1.start();
if (oa2.isRunning()) {
oa2.end();
oa2 = ObjectAnimator.ofFloat(btn2LT, "alpha", 0.5f, 0);
oa2.setDuration(HEARTBEAT_STOP_DURATION);
oa2.setRepeatCount(0);
oa2.setRepeatMode(ValueAnimator.RESTART);
oa2.start();
}
if (oa3.isRunning()) {
oa3.end();
oa3 = ObjectAnimator.ofFloat(btn3LB, "alpha", 0.5f, 0);
oa3.setDuration(HEARTBEAT_STOP_DURATION);
oa3.setRepeatCount(0);
oa3.setRepeatMode(ValueAnimator.RESTART);
oa3.start();
}
if (oa4.isRunning()) {
oa4.end();
oa4 = ObjectAnimator.ofFloat(btn4RB, "alpha", 0.5f, 0);
oa4.setDuration(HEARTBEAT_STOP_DURATION);
oa4.setRepeatCount(0);
oa4.setRepeatMode(ValueAnimator.RESTART);
oa4.start();
}
}
}
After refactored: this is not working.
private void start1HeartBeat() {
startHeartBeat(oa1, btn1RT);
stopHeartBeat(oa2, btn2LT);
stopHeartBeat(oa3, btn3LB);
stopHeartBeat(oa4, btn4RB);
}
private synchronized void startHeartBeat(ObjectAnimator oa, Object btn) {
oa = ObjectAnimator.ofFloat(btn, "alpha", 1, 0);
oa.setDuration(HEARTBEAT_RUN_DURATION);
oa.setRepeatCount(ValueAnimator.INFINITE);
oa.setRepeatMode(ValueAnimator.REVERSE);
oa.start();
}
private synchronized void stopHeartBeat(ObjectAnimator oa, Object btn) {
if (oa.isRunning()) {
oa.end();
oa = ObjectAnimator.ofFloat(btn, "alpha", 0.5f, 0);
oa.setDuration(HEARTBEAT_STOP_DURATION);
oa.setRepeatCount(0);
oa.setRepeatMode(ValueAnimator.RESTART);
oa.start();
}
}
To understand the problem we should be clear about the difference between pass-by-value and pass-by-reference. For the case of Java, this post better clarifies the concept.
In short, in Java the reference itself is pass-by-value. As we know in pass-by-value the change inside a method is not reflected outside. Hence changing the passed reference inside a method is not reflected outside.
With this knowledge, one of the way to correctly refactor the code is as follows
private void start1HeartBeat() {
oa1 = startHeartBeat(oa1, btn1RT);
oa2 = stopHeartBeat(oa2, btn2LT);
oa3 = stopHeartBeat(oa3, btn3LB);
oa4 = stopHeartBeat(oa4, btn4RB);
}
private synchronized ObjectAnimator startHeartBeat(ObjectAnimator oa, Object btn) {
oa = ObjectAnimator.ofFloat(btn, "alpha", 1, 0);
oa.setDuration(HEARTBEAT_RUN_DURATION);
oa.setRepeatCount(ValueAnimator.INFINITE);
oa.setRepeatMode(ValueAnimator.REVERSE);
oa.start();
return oa;
}
private synchronized ObjectAnimator stopHeartBeat(ObjectAnimator oa, Object btn) {
if (oa.isRunning()) {
oa.end();
oa = ObjectAnimator.ofFloat(btn, "alpha", 0.5f, 0);
oa.setDuration(HEARTBEAT_STOP_DURATION);
oa.setRepeatCount(0);
oa.setRepeatMode(ValueAnimator.RESTART);
oa.start();
}
return oa;
}
I just mentioned one possible way to refactor. Since the core problem is clarified, you do refactor in an appropriate way.