带动画的窗口管理器

Posted

技术标签:

【中文标题】带动画的窗口管理器【英文标题】:Windowmanager with Animation 【发布时间】:2011-10-13 22:59:51 【问题描述】:

首先感谢所有尝试回复此主题的人。

我有一个活动,我想在屏幕顶部显示一种菜单,我使用 windowmanager 来处理它。这是关于我遇到的 UI 问题,为什么我选择 windowmanager 来做这样的菜单。但现在我想让这个菜单动画,但动画似乎没有效果。这是我的代码。

如果有人知道如何为 windowmanager 设置动画,我将不胜感激。

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);

提前致谢。问候。

【问题讨论】:

我也在努力解决同样的问题。你找到解决办法了吗? 是的,我也想做这样的事情,但我无法让任何动画工作。 【参考方案1】:

首先,为了您自己的理智,请不要像这样对一堆常量进行硬编码。窗口管理器服务的名称是Context.WINDOW_SERVICE。窗口类型为WindowManager.LayoutParams.TYPE_PHONE。你设置的标志是……嗯……WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL|WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE(说真的,也是用十进制写的??)。格式为PixelFormat.RGBA_8888(我强烈建议改用PixelFormat.TRANSLUCENT)。

现在,首先,使用TYPE_PHONE 到底在做什么?你不想那样做。如果你想在你的主窗口之上有一个分层的窗口,你应该使用TYPE_APPLICATION。事实上,我强烈建议您使用 Dialog 并将其附加窗口设置为您想要的。它将处理使用窗口管理器的所有细节,并且不会以任何方式限制您如何为其设置动画。

我认为您在这里遇到的主要问题是您正在尝试为窗口的根视图设置动画。根视图有些特殊——它定义了窗口的最顶部,与窗口完全匹配,并且总是强制为窗口的大小。它是驱动其子窗口布局的原因。如果你想做一个视图动画,你应该不理会根视图(它是窗口的锚点)并动画它里面的元素。

也就是说,由于您使用的是旧式动画,因此有一种更好的方法来为整个窗口设置动画,例如系统为对话框和活动设置动画的方式等:在窗口的布局参数中设置动画。然后窗口管理器将按照您的指定将该动画应用到整个窗口表面。这比在窗口内做效率更高,因为动画的每一帧只需要用新的动画变换重新合成屏幕,而不是重新绘制窗口内容然后重新合成它。

您可以通过设置WindowManager.LayoutParams.windowAnimations 来做到这一点。这是一个整数字段,它采用定义与窗口相关的各种动画的 style 资源的资源 ID。例如,用于标准对话框的样式是:

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

您将windowEnterAnimation 设置为在窗口显示时运行的动画资源,并将windowExitAnimation 设置为在窗口隐藏时运行的动画资源。如果未设置,则不运行动画。

因此,对于您的代码,您只需创建一个对话框,将其内容设置为您的自定义内容,将其重力、宽度和高度设置为您在此处拥有的值,并将其 windowAnimations 字段设置为您定义的样式动画。如果您想要一些与默认对话框不同的行为(不是触摸模式等),您还可以调整标志。 Dialog.getWindow() 上的 API 拥有设置布局参数所需的一切。

【讨论】:

补充 Dianne 的答案,如果您决定使用 windowAnimations 字段,则指定的常量必须是系统资源;它不能是应用程序资源,因为窗口管理器无权访问应用程序。请参阅documentation。 使用WindowManager.windowAnimations时如何设置动画监听?【参考方案2】:

mParams.windowAnimations = android.R.style.Animation_Toast;

【讨论】:

这很简短。你能添加一些文字来解释它是如何工作的以及它是如何解决问题的吗?【参考方案3】:
mParams.windowAnimations = android.R.style.Animation_Toast;

其中 android.R.style.Animation_Toast 是定义用于此窗口的动画的样式资源。这必须是系统资源,不能是应用程序资源,因为窗口管理器无权访问应用程序。

其他有效的样式是:

mParams.windowAnimations = android.R.style.Animation_Translucent;
mParams.windowAnimations = android.R.style.Animation_Dialog;

【讨论】:

以上是关于带动画的窗口管理器的主要内容,如果未能解决你的问题,请参考以下文章

如何通过onclick list项打开带动画的alertdialog? [关闭]

Qt-布局管理器

Linux 桌面平铺管理器 - i3wm

JavaSE基础(十 二 )---<GUI>GUI概述,Swing,容器组件,窗口,面板,布局管理器

Excel VBA - 从多个打开的文件资源管理器窗口中关闭特定的文件资源管理器窗口

为 Linux 构建 3D 窗口管理器