就像windows系统里最普通但是被设置了TOPMOST的EX_STYLE的窗口一样,具体来说就是不独占全屏,不独占焦点,可移动,可改变大小,总在最顶层的窗口。主要用来做网络流量的流量计,或者给后台运行的需要随时观察数据变化的程序一个大点的观察窗口之类的用途。google了很久,只找到了一些似是而非的方案,主要有下面2个说法:1,将 Activity 的 Theme 设置为 Theme.Dialog,Theme.Panel,Theme.InputMethod 之类,这样做的实际效果是,分别将窗口的 windowFrame,windowIsFloating,windowIsTranslucent,disabledAlpha 以各种方式组合得来,都无法达到要求的效果。2,使用 PopupWindow,但是 PopupWindow 必须有一个 View 作为 parent,这就避不开 Activity 全屏独占的问题,而且当其下的 Activity 切换的时候这个popupWindow也没了,所以也不行。
不知道有没有高手找到解决方法?

解决方案 »

  1.   

    流量统计,直接放到notification 状态栏好了,不然你就不怕用户骂你遮挡视线吗
      

  2.   

    这个问题很有意义,就是一个可拖动的窗口。不是遮挡视线的问题,用好了还有很大的帮助。
    比如,想同时看到背后屏幕和拖动窗口的信息,这就是个很好的实现方法。如果能够把窗口部分拖出屏幕就更好了。notification还是不能满足同时看见的要求。我也来试试看怎么做到。
      

  3.   

    直接放到桌面上,成为一个appWidget即可,桌面小插件。
      

  4.   

    3楼的同志,appWidget 只能放在特定的宿主程序上(宿主程序里面必须有AppWidgetHost),与我的要求不合。
    如2楼所说,只是需要找出这样一个机制,流量统计窗口实际上只是其中一种应用而已。这样的机制在windows下是天生的,但是在andriod上由于其ui体系的设计特性——考虑到小屏幕显示设备上不适宜出现跨进程的多窗口重叠——而没有官方的渠道做到这一点。目前我能做到让窗口显示在其他顶层之上,但是在交互上会出现应用程序焦点独占的问题。基本思路是使用 WindowManager.addView 来创建这种漂浮窗口,窗口的具有 TYPE_SYSTEM_ALERT 属性,保证了其始终位于顶层。由于 Activity 是全屏独占的,会屏蔽掉其下方的窗口与用户操作的交互,所以 WindowManager 不能依赖在 Activity 上,而只能在 Service 中调用。具体做法是:
    1. 应用必须具有 <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"></uses-permission> 的权限
    2. 从一个 Activity 启动,在该 Activity 中 startService,然后在 Service 中调用 WindowManager.addView,被添加的 view 应该设置 FLAG_NOT_TOUCH_MODAL 标志
    3. 为成为漂浮窗口的 view 设置 OnTouchListener,处理 OnTouch 事件的 ACTION_DOWN 和 ACTION_MOVE 使漂浮窗体可以被拖动
    4. 在窗体关闭的过程中 finishService,或者在漂浮窗体计数器上减1之类,保证Service能够被正确结束但是这种实现有焦点独占的问题:当漂浮窗口存在于屏幕上时,焦点将始终处于悬浮窗口上。有一种折中的办法是,为 view 设置 FLAG_WATCH_OUTSIDE_TOUCH 标志,然后在 ACTION_OUTSIDE 中将 view 设置为 setFocusable(false)。但是这样的话,在放弃焦点之后就无法再对悬浮窗口进行操作了。现在有2个问题:
    1. 如果不使 view 放弃焦点,那么如何使焦点正常转移到下方的 Activity 上?
    2. 如果使 view 在 ACTION_OUTSIDE 中放弃焦点,那么如何使交互操作进入悬浮窗口所在区域的时候重新使悬浮窗口获取焦点?以上2个问题只要能解决一个就可以了。
    第1个问题设计到ui体系的框架设计了,大概没什么后天的办法可以改动,除非修改ui体系的设计,估计难度很大。
    第2个问题,如果有全局监听输入事件(主要是触摸事件的ACTION_DOWN)的发生坐标的方法,就可以解决这个问题,还请牛人支招。
      

  5.   

     你的标题说的这几个条件在android上可能无法同时成立,非独占还能拖动还在最顶层,焦点一直在你的应用上,我也感兴趣,哈哈
      

  6.   

    android好像不支持同时好几个窗口吧,呵呵
      

  7.   

    up一下
    2.如果有全局监听输入事件(主要是触摸事件的ACTION_DOWN)的发生坐标的方法
    这个应该容易实现吧?
    继续调查一下,应该有办法获得当前触摸点的坐标
      

  8.   

    public boolean onTouchEvent (MotionEvent event) 
    MotionEvent可以获取当前的坐标
    For efficiency, motion events with ACTION_MOVE may batch together multiple movement samples within a single object. The most current pointer coordinates are available using getX(int) and getY(int). Earlier coordinates within the batch are accessed using getHistoricalX(int, int) and getHistoricalY(int, int). 
      

  9.   


    对于没有焦点的窗口是拿不到这个事件的,Touch事件只会像当前具有焦点的窗口广播。前面说的解决方案中,在 ACTION_OUTSIDE 里面已经将本窗口设置为没有焦点了,所以放弃焦点之后即使是点在悬浮窗口的区域也是拿不到事件的,这个事件会直接发送到悬浮窗口之下的那一层去。
      

  10.   

    弱弱的说一个,或者可以考虑ShowToast,然后自定义视图。我没记错的话,时间可以控制它显示的时间!
      

  11.   

    我试过Toast,Toast也是无焦点的窗口,不能监听到Touch事件
      

  12.   

    在主view的touch时间里面set toast也许可以, 比如 vMain.setOnClickListener
            (
             new OnClickListener()
             {
             @Override
             public void onClick(View v)
             {
             // This is the first way to customize Toast
             // center and shift 50px to right, 100px down
             tView.setGravity(Gravity.CENTER_VERTICAL, 50, -150);
             tView.setText("This is a Custom Toast\nScreen is clicked\nGravity: Virtical Center, X 50, Y -150\nDuration: LONG");
             tView.setDuration(Toast.LENGTH_LONG);         tView.show();
             }
             }
            );我点了下tView这个toast,他动了一下,表明点在toast上面其实主view时间监听的。你自己试试看onTouchAOA(傲卓网)
      

  13.   

    toast因为是不具有焦点的类,所以点在toast上其实是事件穿过了toast到达位于toast下层的应用的view,如果toast显示在别的程序窗口上方,接收到touch的就是别的程序,而不是toast的owner了
      

  14.   

    "对于没有焦点的窗口是拿不到这个事件的,Touch事件只会像当前具有焦点的窗口广播。"
    根本解决方案:扩展一个UI componet,更改framework层焦点处理manage和触摸事件分发机制,对此UI componte进行特殊处理。个人建议回避这个问题,选择下述方案:
    更改你的APP layout,把你需要加的这个小窗口作为整个activity的一部分进行处理,比如设计成是activity的一个item,放在底部或者顶部,不然现有机制无法解决。这样做功能能实现,只是效果差一点。
      

  15.   

    提供个思路
    布局文件里用FrameLayout布局
    全屏的最底层 和 浮动的上层 分别放在两个Layout中
    上层覆盖住底层的一部分
    上层和没被盖住的底层可以同时获得焦点
      

  16.   

    楼上的兄弟你搞错了,我需要的是1.窗口在没有焦点的情况下仍然处于最顶层,并且
    2.当touch事件发生在悬浮窗口区域内部时,该touch事件能够被悬浮窗口捕捉到
      

  17.   

    http://www.eoeandroid.com/thread-58679-1-1.html
      

  18.   

    仔细看过24楼给的例子,发现标志里多了一个 FLAG_NOT_FOCUSABLE,这样就解决焦点问题了。
      

  19.   

    楼主解决了么~我的感觉是窗口不会永远在最顶层的,只能在当前的上下文中保持最顶层。还是说我对楼主的理解有误~WindowManager.LayoutParams.type中能设置的参数都达不到要求。
      

  20.   

    http://hiapk.com/thread-1046140-1-1.html
    请参考上面的源码
      

  21.   

    QQ手机管家就已经实现了这样的功能。
    我也在思考它是怎么做出来的。不知道楼主实现了没?
    Share ?