I want to animate it to slide down from the top.
After you call WindowManager.addView
you can attach a ViewTreeObserver.OnGlobalLayoutListener
to the View
and use that to get the height, then use an ObjectAnimator
to perform the translation. Here's an example:
mMessage.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
// Get the height of the view
final int h = mMessage.getHeight();
// Remove the OnGlobalLayoutListener callback
mMessage.getViewTreeObserver().removeOnGlobalLayoutListener(this);
// Slide down from the top
final ObjectAnimator oa = ObjectAnimator.ofFloat(mMessage, "translationY", -h, 0f);
oa.setDuration(250);
oa.start();
}
});
If you want to slide it back up later, perform the opposite translation and attach an AnimatorListener
to know when to call WindowManager.removeViewImmediate
. For instance:
private void removeLoadingMessage(boolean animate) {
if (mMessage != null && mMessage.getWindowToken() != null) {
// Detach the View immediately, don't wait for the animation to end
if (!animate) {
getWindowManager().removeViewImmediate(mMessage);
mMessage = null;
return;
}
// Slide back up
final int h = mMessage.getHeight();
final ObjectAnimator oa = ObjectAnimator.ofFloat(mMessage, "translationY", 0f, -h);
oa.setDuration(250);
// Wait until the end of the animation to detach the View
oa.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
getWindowManager().removeViewImmediate(mMessage);
mMessage = null;
}
});
oa.start();
}
}
To avoid any leaks, in Activity.onDestroy
you'd want to use removeLoadingMessage(false);
to ensure the View
to properly detached from the Window
.