229

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

4

3 回答 3

219

这个

允许应用程序使用 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));

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

于 2013-04-12T21:11:53.720 回答
52

通常,Android 活动是全屏的、概念上专用的 UI,可以进行所有交互。有几个例外。首先,有一些不会填满屏幕的弹出对话框。另一个是Android toast,它是一个非交互式弹出窗口——你不能触摸它,如果你尝试它会转到下面的任何东西。

您也可以制作自己的特殊 UI。您可以将视图直接添加到WindowManager,指定类型标志。聊天头可能使用TYPE_PHONE。有一些类似的类型,但目的是一样的:特殊用途的覆盖可以出现在其他任何东西的顶部,而父应用程序显然不存在。

但是,由于交互问题,这只能使您到目前为止。一开始,你的叠加层会吸收所有的交互,所以不仅头部会得到事件,而且你会阻止与下面所有东西的交互。

您可以使用LayoutParams配置此行为。FLAG_NOT_TOUCH_MODAL意味着显示区域之外的事件会转到底层 UI。您现在会发现它可以工作,但是其他不好的事情仍然会发生,例如后退/菜单按钮没有定向到应用程序,而且没有键盘。要解决您需要FLAG_NOT_FOCUSABLE的 .

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

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

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

于 2013-04-15T15:41:17.147 回答
7

Springy Heads提供了开箱即用的基于弹簧的聊天头行为。您只需定义聊天头的可绘制对象和单击聊天头后要打开的片段。聊天头在最小化时折叠并在拖动时跟随手指。

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

compile 'com.flipkart.springyheads:library:0.9.6'
于 2015-12-29T09:07:31.150 回答