To do this, I made an auxiliary class to listen for events of Motion
in ToggleButton
, which in sequence:
Starts an alpha animation from 1 to 0, leaving ToggleButton
transparent.
Using ToggleButton
transparent modifies its state using setChecked
Then start an alpha animation from 0 to 1 to display the new status.
The helper class is:
public class DrawableTransition extends GestureDetector.SimpleOnGestureListener implements View.OnTouchListener, Animation.AnimationListener {
WeakReference<ToggleButton> mToggle;
GestureDetector mGestureDetector;
AlphaAnimation mAlphaTo0, mAlphaTo1;
public DrawableTransition(Context context, ToggleButton toggle) {
mToggle = new WeakReference<ToggleButton>(toggle);
mGestureDetector = new GestureDetector(context, this);
mAlphaTo1 = new AlphaAnimation(0f, 1f);
mAlphaTo1.setDuration(1000l);
mAlphaTo0 = new AlphaAnimation(1f, 0f);
mAlphaTo0.setDuration(1000l);
mAlphaTo0.setAnimationListener(this);
}
@Override
public void onAnimationStart(Animation animation) {}
@Override
public void onAnimationEnd(Animation animation) {
// Animacao de alpha para 0 terminou, vamos mostrar o botao
show();
}
@Override
public void onAnimationRepeat(Animation animation) {}
@Override
public boolean onTouch(View v, MotionEvent event) {
// Delega para o GestureDetector
mGestureDetector.onTouchEvent(event);
return true;
}
// Single tap foi confirmado
@Override
public boolean onSingleTapConfirmed(MotionEvent e) {
return hide();
}
// Troca o estado, com isso alterando o background
// depois iniciando uma animacao de alpha para 1, exibindo o botao novamente
boolean show() {
ToggleButton toggle = mToggle.get();
if(toggle == null) {
return false;
}
toggle.setChecked(! toggle.isChecked());
toggle.startAnimation(mAlphaTo1);
return true;
}
// Faz a animacao de alpha para 0, escondendo o botao
boolean hide() {
ToggleButton toggle = mToggle.get();
if(toggle == null) {
return false;
}
toggle.startAnimation(mAlphaTo0);
return true;
}
/**
* Limpar recursos, a fim de evitar memory leak
* Chamar no onDestroy ou onDestroyView
*/
public void clean() {
mGestureDetector = null;
mToggle.clear();
mToggle = null;
mAlphaTo0 = mAlphaTo1 = null;
}
}
I ended up using GestureDetector
because working only on onTouch
may have false positives of ACTION_UP
. The ACTION_UP
also occurs when he raises his finger off the button, and this is characterized as a cancellation. GestureDetector
can do this treatment, so it's easier to use.
To use:
ToggleButton toggle = findViewById(...);
toggle.setOnTouchListener(new DrawableTransition(getApplicationContext(), toggle));