21

我想制作一个可以在当前显示的任何内容之上的屏幕上创建通知的应用程序。类似于 Go SMS 消息弹出窗口或类似于下图中的 ChatHead 的内容:

在此处输入图像描述

如果可以动态地绘制它,包括触摸事件,那就更好了。这样做的传统或标准方法是什么?

例子:

就像一个可以点击或拖动的图标,无论您是在主屏幕还是应用程序抽屉或其他应用程序。注意发布图片中靠近屏幕边缘的圆形图标。您可以将它们拖动到任何应用程序的任何位置。

4

5 回答 5

11

您正在寻找的是系统警报窗口。

有一个名为StandOut的库!这将帮助您创建此类应用程序。

于 2013-07-21T09:11:52.943 回答
10

以下是 Toast 和对话框窗口之类的工作方式:

在仅添加或置于前面不起作用的情况下,例如当您让服务将其自己的视图添加到另一个客户端活动或应用程序(FaceUnlock 执行此操作),或者您不能依赖层次结构时,您需要使用窗口经理和一个窗口令牌来做这个伎俩。然后,您可以像以前一样创建布局并利用动画和硬件加速。

    WindowManager windowManager = (WindowManager) getBaseContext().getSystemService(Context.WINDOW_SERVICE);

    WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams(WindowManager.LayoutParams.FIRST_SUB_WINDOW);
    layoutParams.width = 300;
    layoutParams.height = 300;

    layoutParams.format = PixelFormat.RGBA_8888;
    layoutParams.flags =
            WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
                    | WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
    layoutParams.token = getWindow().getDecorView().getRootView().getWindowToken();

    //Feel free to inflate here
    mTestView = new View(this);
    mTestView.setBackgroundColor(Color.RED);

    //Must wire up back button, otherwise it's not sent to our activity
    mTestView.setOnKeyListener(new View.OnKeyListener() {
        @Override
        public boolean onKey(View v, int keyCode, KeyEvent event) {
            if (keyCode == KeyEvent.KEYCODE_BACK) {
                onBackPressed();
            }
            return true;
        }
    });
    windowManager.addView(mTestView, layoutParams);

然后一定要删除视图onDestroy(或onPause)否则你会崩溃

   if (mTestView != null) {
       WindowManager windowManager = (WindowManager) getBaseContext().getSystemService(Context.WINDOW_SERVICE);
       if (mTestView.isShown()) {
            windowManager.removeViewImmediate(mTestView);
       }
   }
于 2015-04-03T17:24:53.003 回答
9

您不需要新的活动来执行此操作。您需要做的就是在现有活动中添加另一个视图并将其放在前面,然后在该视图中绘制/写入您想要的东西。

如果你想用这个额外的视图做一些特殊的事情,你可以创建自己的视图类

class DrawOnTop extends View { 
    public DrawOnTop(Context activity) { 
        super(activity);
    }

    @Override 
    protected void onDraw(Canvas canvas) {
        // put your drawing commands here
    }

}

然后你做类似的事情

DrawOnTop mDraw = new DrawOnTop(this);
addContentView(mDraw, new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
mDraw.bringToFront();

然后要强制它绘制,你需要使用 mDraw.invalidate();

于 2013-04-28T15:53:30.437 回答
1

您可以将整个布局的父级设置为 RelativeLayout。第一个孩子是主布局的“根”。之后的任何内容都可以被认为是一个覆盖层,可以随心所欲地放置。

例子:

<RelativeLayout>
  <LinearLayout>
    ... Main Layout here ...
  </LinearLayout>

  <TextView left="20dip" top="20dip" text="Overlay" alpha="0.7" />
</RelativeLayout>
于 2013-04-28T15:59:49.490 回答
1

最好的方法是使用您的应用程序启动服务。创建一个图像视图。设置 Image View 的 LayoutParams。创建服务时,将视图与参数一起添加到窗口管理器。

全部设置您的图像会粘在您的窗口上(在所有应用程序的任何屏幕上),直到您的应用程序关闭。

您甚至可以将 onclicklisteners 和 ontouchlisteners 添加到 imageview。例如。OnClick 侦听器执行一些操作,而 Ontouchlisteners 沿着屏幕移动图像。

于 2016-08-19T10:42:08.390 回答