如何将浮动视图添加到Android窗口管理器并监听系统/硬件返回按钮事件

12

我有一个服务,可以在窗口管理器上显示浮动视图(使用WINDOW_TYPE_ALERT权限)。我能够显示它并执行操作。但是,我有两个具体的问题:

  1. 关于浮动视图的实现
  2. 如何监听系统返回按钮事件以便我可以关闭视图。

实现:

在清单文件中,我添加了以下权限:

<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />

我有一个广播接收器,它将监听闹钟事件。在接收到该事件时,我会启动一个服务来显示悬浮视图。以下是我用来创建该视图的代码。

LayoutParams layOutParams = new WindowManager.LayoutParams(
                WindowManager.LayoutParams.TYPE_SYSTEM_ALERT,
                WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH,
                PixelFormat.TRANSLUCENT);
每当用户在视图上执行任何操作时,我都会将该视图从窗口管理器中移除并停止服务。
我想知道的是,这是否是解决问题的正确方式,或者是否有更好的方法?另外,我应该对LayoutParams进行更改还是保持原样?
其次,当系统返回/硬件返回按钮被按下时,我也想关闭这个浮动视图。如何实现这一点?附上一个浮动视图的截图以便更好地理解:

Floating View


只需显示一个对话框,它将为您处理事件。 - Andrew Matiuk
@veon,你能告诉我在哪里添加对话框吗? - Handroid
5个回答

11

关于返回按钮检测 - 我通过以下方式使其工作(所有操作都在服务的 onCreate 代码中完成):

  1. 将你想要检测的视图包装到 ViewGroup 中(如 LinearLayout、Relative 或其他)
  2. 在包装器视图中像这样覆盖 dispatchKeyEvent:

mView = new RelativeLayout(this) {
        @Override
        public boolean dispatchKeyEvent(KeyEvent event) {
            if (event.getKeyCode()==KeyEvent.KEYCODE_BACK) {
                // < your action >
                return true;
            }
            return super.dispatchKeyEvent(event);
        }
};
  1. 将包装视图添加到窗口管理器,并确保在包装布局参数上未设置 WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE。

你是如何使这个工作的?我无法触摸任何东西/滚动。 - John61590

6
请看Standout库,它很适合处理浮动窗口,但好像不能处理后退事件,联系开发人员可能有帮助。
还有一种方法是尝试使用半透明背景/主题打开活动,以获得类似于Any.do中使用的浮动窗口效果,并可以处理后退事件。

3
谢谢你的答复,你确实指出了我的正确方向。为了完全让它像Any.do一样工作,我必须执行以下操作:我们必须使用"singleInstance"启动模式来启动活动。我们需要在清单文件中这样提及它:android:launchMode="singleInstance" - Handroid

1

您是否希望 HOME 按钮也可以关闭您的 UI?如果是的话,最好使用一个在透明背景上打开的活动,而不是警告窗口。为此,请使用以下样式作为活动的主题。

<style name="Transparent">
    <item name="android:windowFrame">@null</item>
    <item name="android:windowBackground">@color/transparent</item>
    <item name="android:windowIsFloating">true</item>
    <item name="android:windowContentOverlay">@null</item>
    <item name="android:windowAnimationStyle">@android:style/Animation.Dialog</item>
    <item name="android:windowSoftInputMode">stateUnspecified|adjustPan</item>
    <item name="android:windowFullscreen">true</item>
</style>

1
关于后退按钮 - 您应该在视图内重写 "onBackPressed()" 并执行您想要的任何操作。
@Override
public boolean onBackPressed() {
    // Remove your view from the window...
}

无论如何,我正在使用名为Tooleap的SDK,在简单明了的方式下显示浮动窗口。 点击此处 了解更多信息。

onBackPressed() 不是一个 View 方法,因此无法被重写。但是你可以重写 dispatchKeyEvent(KeyEvent event) 并查找返回按键。 - Birdnado

-1

关于处理“onBackpressed”按钮,请按照以下步骤:

1.转到示例中的FlotingFolder.java文件(非库文件)。

2.查找下面的方法

@Override
public int getFlags(int id) {
    if (APP_SELECTOR_ID == id) {
        return super.getFlags(id);
    } else {
        return super.getFlags(id) | StandOutFlags.FLAG_BODY_MOVE_ENABLE
                | StandOutFlags.FLAG_WINDOW_EDGE_LIMITS_ENABLE
                | StandOutFlags.FLAG_WINDOW_FOCUSABLE_DISABLE;
    }
}
  1. 然后从上述方法中删除“StandOutFlags.FLAG_WINDOW_FOCUSABLE_DISABLE”

现在onBackPressed将会起作用。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接