哪些API用于覆盖其他应用程序(如Facebook的Chat Heads)?


226

Facebook如何在Android上创建聊天头?在所有其他视图之上创建浮动视图的API是什么?


6
此应用程序还具有“聊天头” play.google.com/store/apps/details?id=com.ninja.sms
Oli 2013年

11
如果您正在寻找示例,请参见github.com/marshallino16/FloatingNotification
marshallino16

5
您可以在此处找到一个演示和一个简单的库:github.com/ericbhatti/floaties使用此库,您仅需两行就可以创建浮动窗口。
埃里克·B。

Answers:


217

这个

允许应用程序使用TYPE_SYSTEM_ALERT类型打开窗口,该窗口显示在所有其他应用程序的顶部。很少有应用程序应使用此许可权。这些窗口用于与用户进行系统级交互。

常数值:“ android.permission.SYSTEM_ALERT_WINDOW”

//编辑:完整代码在这里

public class ChatHeadService extends Service {

  private WindowManager windowManager;
  private ImageView chatHead;

  @Override public IBinder onBind(Intent intent) {
    // Not used
    return null;
  }

  @Override public void onCreate() {
    super.onCreate();

    windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);

    chatHead = new ImageView(this);
    chatHead.setImageResource(R.drawable.android_head);

    WindowManager.LayoutParams params = new WindowManager.LayoutParams(
        WindowManager.LayoutParams.WRAP_CONTENT,
        WindowManager.LayoutParams.WRAP_CONTENT,
        WindowManager.LayoutParams.TYPE_PHONE,
        WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
        PixelFormat.TRANSLUCENT);

    params.gravity = Gravity.TOP | Gravity.LEFT;
    params.x = 0;
    params.y = 100;

    windowManager.addView(chatHead, params);
  }

  @Override
  public void onDestroy() {
    super.onDestroy();
    if (chatHead != null) windowManager.removeView(chatHead);
  }
}

不要忘记以某种方式启动该服务:

startService(new Intent(context, ChatHeadService.class));

..并将此服务添加到您的清单中。


4
我认为还有更多奇怪的东西。如何处理“头部”之外的输入以及可拖动性呢?我认为您至少需要FLAG_NOT_TOUCH_MODAL,以及一些聪明的逻辑来在拖动窗口时更新Window属性(即,移动它)。
Delyan

2
在那如何删除聊天头?
尼拉夫·梅塔

6
我认为值得一提的是我开发的用于创建浮动UI的SDK:www.tooleap.com
Arik

@NiravMehta您可以删除聊天头吗?
KK_07k11A0585 2015年

如何删除聊天头的空白。因为在上面的代码输出中,圆圈与边框之间有一定间距。在Facebook中,气泡没有该间距
Debugger

51

通常,Android活动是全屏,概念上专用的UI,可以进行所有交互。有一些例外。首先,有一些弹出对话框不会填满屏幕。另一个是Android Toast,它是一个非交互式弹出窗口-您无法触摸它,如果尝试,它将转到下面的所有内容。

您也可以做自己的特殊用户界面。您可以将视图直接添加到中WindowManager,并指定类型标记。聊天头可能使用TYPE_PHONE。有几种相似的类型,但是目的是相同的:特殊用途的覆盖层可以出现在其他任何对象的顶部,而显然没有父应用程序存在。

但是,由于交互问题,这只能使您走得更远。首先,您的叠加层将吸收所有互动,因此头部不仅会获取事件,而且还会阻止与下方所有事物的互动。

您可以使用LayoutParams配置此行为。FLAG_NOT_TOUCH_MODAL表示您的显示区域之外的事件将转到基础UI。现在,您会发现它可以工作,但是仍然存在其他不良情况,例如后退/菜单按钮无法定向到应用程序,而且没有键盘。解决您所需要的FLAG_NOT_FOCUSABLE

您也将从不可聚焦的位中得到副作用,这与覆盖层不再是很好的交互,例如,按下按钮。但是,您可以获得一些基本的触摸事件,您可以随时对其进行数学运算,这对于聊天头来说可能就足够了。请注意,它会在很多领域(如UI动画)让您自己动手。

您可以在此StackOverflow线程中找到详细的概述,包括允许选择性的交互消耗。特别是,其中一个答案链接最终将带您到这里,这是一个很好的示例项目。请注意,ICS稍微改变了它的工作方式,但是线程对此做了解释。

这些都是公共API的东西,但是,理所当然,这似乎并不是应该做的主流事情。该文档中充斥着对特殊系统应用程序行为的引用,并且有充分的理由;如果每个人都做了怎么办?


我可以阻止这些视图的方向更改吗?如果基础活动改变了方向,我的看法也将改变他的方向。
MG

1
否。方向更改是在整个设备范围内进行的,而不仅仅是针对活动。
罗伯·普里汉姆

7

弹性头使开箱即用的基于弹簧的聊天头行为成为可能。您需要定义的只是聊天头的可绘制对象,以及单击聊天头后即可打开的片段。最小化时,聊天头会折叠,拖动时会跟随手指。

该项目包括一个演示应用程序,演示了所有内置功能。要使用它,需要将其添加到gradle依赖项中。

compile 'com.flipkart.springyheads:library:0.9.6'

嘿@KiranKumar,您已经创建了一个非常清晰的库。.我只是喜欢它。.我试图从该库中学习各个方面..我一直在尝试在应用程序窗口之外运行它,以某种方式我在此方面略有成功那样。。但是,当我单击应用程序窗口外的聊天头时,就会出现问题。如果无法从您的角度查看该片段,则无法打开该片段并返回java.lang.OutOfMemoryError ..给我通过这个某种方式。它会很高兴地荣幸..
arraystack

@arraystack现在您可以在服务中运行它。检查列表是否在GitHub存储库中有分支
Kiran Kumar

@KiranKumar谢谢,新lib的问题是棉花糖版本中Draw over application的权限
arraystack 2016年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.