Reputation: 5637
I'm doing this bar
showing-refreshing-message-in-action-bar
It's work just fine.However, I want to animate it to slide down from the top.
I can animate other object which create in layout but not by getWindowManager().addview
This is work for my object in current layout
switch(item.getItemId())
{
case R.id.zoomInOut:
TextView image = (TextView)findViewById(R.id.textView);
Animation animation = AnimationUtils.loadAnimation(getApplicationContext(), R.anim.myanimation);
image.startAnimation(animation);
return true;
case R.id.rotate360:
TextView image1 = (TextView)findViewById(R.id.textView);
Animation animation1 = AnimationUtils.loadAnimation(getApplicationContext(), R.anim.clockwise);
image1.startAnimation(animation1);
return true;
case R.id.fadeInOut:
TextView image2 = (TextView)findViewById(R.id.textView);
Animation animation2 = AnimationUtils.loadAnimation(getApplicationContext(), R.anim.fade);
image2.startAnimation(animation2);
return true;
}
This is not work for my view that add by getWindowManager().addview
/** The notification layout */
private TextView mMessage;
public void showLoadingMessage(Context context,String msg) {
// Initialize the layout
if (mMessage == null) {
final LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
mMessage = (TextView) inflater.inflate(R.layout.test, null);
mMessage.setBackgroundColor(getResources().getColor(R.color.holo_green_light));
mMessage.setText(msg);
}
// Add the View to the
getWindowManager().addView(mMessage,getActionBarLayoutParams());
//ANIMATION FOR THIS LAYOUT START HERE
Animation aa = AnimationUtils.loadAnimation(getApplicationContext(), R.anim.fade);
mMessage.startAnimation(aa);
}
public void removeLoadingMessage() {
if (mMessage != null && mMessage.getWindowToken() != null) {
getWindowManager().removeViewImmediate(mMessage);
mMessage = null;
}
}
private WindowManager.LayoutParams getActionBarLayoutParams() {
// Retrieve the height of the status bar
final Rect rect = new Rect();
getWindow().getDecorView().getWindowVisibleDisplayFrame(rect);
final int statusBarHeight = rect.top;
// Create the LayoutParams for the View
final WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,200,
WindowManager.LayoutParams.TYPE_APPLICATION_PANEL,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, PixelFormat.TRANSLUCENT);
// params.gravity = Gravity.TOP;
params.x = 0;
params.y = statusBarHeight;
return params;
}
Upvotes: 1
Views: 940
Reputation: 30794
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
.
Upvotes: 1