如何在一切之上绘制视图?

时间:2013-04-28 15:50:44

标签: java android view notifications

我想创建一个可以在屏幕上创建当前正在显示的任何内容的通知的应用。类似于Go SMS消息弹出窗口或类似ChatHead的东西,如下图所示:

enter image description here

如果有可能动态绘制它包括触摸事件会更好。传统或标准的方法是什么?

示例:

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

5 个答案:

答案 0 :(得分:10)

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

有一个名为StandOut的图书馆!这将有助于您创建此类应用程序。

答案 1 :(得分: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);
       }
   }

答案 2 :(得分: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();

答案 3 :(得分:1)

您可以将整个布局的父级设为RelativeLayout。第一个孩子是主要布局的“根”。之后的任何事情都可以被视为一种可以放在你的想法上的叠加层。

示例:

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

  <TextView left="20dip" top="20dip" text="Overlay" alpha="0.7" />
</RelativeLayout>

答案 4 :(得分:1)

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

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

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