Windowmanager with Animation

Omer Faruk KURT picture Omer Faruk KURT · Jul 27, 2011 · Viewed 7.5k times · Source

First of all thanks everyone who tries to reply this topic.

I have an activity and I wanted to show a sort of menu at the top of the screen and I used windowmanager to handle this. it was about UI issues I encountered why I choise windowmanager to do such a menu. But for now I want this menu to animate but it seems animation takes no effect. Here is my code.

If anyone has any idea how to animate windowmanager I ll be appreciate.

Animation animShowTopLine;

animShowTopLine = AnimationUtils.loadAnimation(this, R.anim.translate);
        animShowTopLine.reset();
LinearLayout top_line;
WindowManager wm;
WindowManager.LayoutParams wmParams;

LayoutInflater inflate = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);

    top_line =    (LinearLayout) inflate.inflate(R.layout.line, null);

    wm =(WindowManager) getApplicationContext().getSystemService("window");

    wmParams =new WindowManager.LayoutParams();

    wmParams.type=2002;
    wmParams.format = 1;
    wmParams.flags=40;
    wmParams.width=WindowManager.LayoutParams.FILL_PARENT;
    wmParams.height=WindowManager.LayoutParams.WRAP_CONTENT;

    wmParams.gravity  = Gravity.TOP;

    wm.addView(top_line, wmParams);


    top_line.startAnimation(animShowTopLine);

Thanks in advance. Regards.

Answer

hackbod picture hackbod · Jan 8, 2013

First, please for your own sanity don't hard-code a bunch of constants like that. The name of the window manager service is Context.WINDOW_SERVICE. The window type is WindowManager.LayoutParams.TYPE_PHONE. The flags you have set is... ummm... WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL|WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE (seriously, written in decimal as well??). The format is PixelFormat.RGBA_8888 (and I would strongly recommend using PixelFormat.TRANSLUCENT instead).

Now, first, what in the world are doing using TYPE_PHONE? You don't want to do that. If you want a window layered on top of your main window, you should be using TYPE_APPLICATION. In fact, I would urge you to just use Dialog for this and set its attached window to be what you want. It will take care of all the details of working with the window manager, and doesn't limit you in any way with how you can animate it.

I think the main problem you have here is that you are trying to animate the root view of the window. The root view is somewhat special -- it defines the top-most part of the window, exactly matches the window, and is always forced to be the size of the window. It is what drives the layout of its child windows. If you want to do a view animation, you should leave the root view alone (it is the anchor of the window) and animate the elements inside of it.

That said, since you are using an old-style animation, there is a better way to animate full windows, the way that the system animates dialogs and activities and such: set the animation in the window's layout params. Then the window manager will apply that animation to the entire window surface as you specify. This is more efficient than doing it inside of the window because each frame of the animation only requires re-compositing the screen with the new animation transformation, instead of re-drawing the window contents and then re-compositing it.

You do this by setting WindowManager.LayoutParams.windowAnimations. This is an integer field that takes the resource id of a style resource defining the various animations associated with the window. For example, the style used for the standard dialogs is:

<style name="Animation.Dialog">
    <item name="windowEnterAnimation">@anim/dialog_enter</item>
    <item name="windowExitAnimation">@anim/dialog_exit</item>
</style>

You set windowEnterAnimation to the animation resource to run when the window is being shown, and windowExitAnimation to the one to run when it is hidden. If not set, no animation is run.

So for your code here, you can just make a Dialog, set its content to your custom content, set its gravity, width and height to the values you have here, and set its windowAnimations field to your style defining the animations. You can also tweak the flags if you want some behavior different than a default dialog (not touch modal or such). The API on Dialog.getWindow() has everything you need to set the layout params.