【问题标题】:How to draw a view on top of everything?如何在一切之上绘制视图?
【发布时间】:2013-04-22 07:02:03
【问题描述】:

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

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

示例:

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

【问题讨论】:

  • 查看这个问题的答案:stackoverflow.com/questions/2176922/…
  • 这么透明不会消耗所有的触摸事件?
  • 是的,但是如果您在另一个活动的顶部绘图,这通常是您想要的。如果用户触摸外部,请关闭您的视图。我的建议是。
  • 成功了吗?我也需要。
  • stackoverflow.com/questions/16559642/… 由同一个人问,但它确实有答案。

标签: java android view notifications


【解决方案1】:

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

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

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

【讨论】:

  • 代码或它没有发生:/
【解决方案2】:

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);
       }
   }

【讨论】:

    【解决方案3】:

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

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

    【讨论】:

      【解决方案4】:

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

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

      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();

      【讨论】:

      • 我的意思是像一个可以点击或拖动的图标,无论您是在主屏幕上还是应用程序菜单或其他应用程序上
      • 我已经使用我发布的内容在活动的主视图顶部绘制文本和位图。我猜你也可以用它来做你建议的事情。
      • 对不起,我想我的问题放错了!我想绘制其他应用而不是我自己的应用
      • @Stochasticly,您不知道哪里有您的代码的大量实现吗?多年来,我一直在尝试自己的版本,但无法将其绘制在视图之上。
      • @Gurfuffle 自去年以来我就没有参与过 Android 编码,所以不确定代码在哪里。对不起!
      【解决方案5】:

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

      例子:

      <RelativeLayout>
        <LinearLayout>
          ... Main Layout here ...
        </LinearLayout>
      
        <TextView left="20dip" top="20dip" text="Overlay" alpha="0.7" />
      </RelativeLayout>
      

      【讨论】:

      • 你是对的,但就我而言,我是在主屏幕等其他应用程序之上绘图
      猜你喜欢
      • 2013-06-25
      • 2017-03-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-14
      • 2016-12-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多