android编程实现悬浮窗体的方法

时间:2022-10-25 12:40:28

本文实例讲述了android编程实现悬浮窗体的方法。分享给大家供大家参考,具体如下:

突然对悬浮窗体感兴趣,查资料做了个小demo,效果是点击按钮后,关闭当前activity,显示悬浮窗口,窗口可以拖动,双击后消失。效果图如下:

android编程实现悬浮窗体的方法

它的使用原理很简单,就是借用了windowmanager这个管理类来实现的。

1.首先在androidmanifest.xml中添加使用权限:

复制代码 代码如下:
<uses-permission android:name="android.permission.system_alert_window" />

 

2.悬浮窗口布局实现

?
1
2
3
4
5
6
7
8
9
10
11
public class desktoplayout extends linearlayout {
  public desktoplayout(context context) {
    super(context);
    setorientation(linearlayout.vertical);// 水平排列
    //设置宽高
    this.setlayoutparams( new layoutparams(layoutparams.wrap_content,
        layoutparams.wrap_content));
    view view = layoutinflater.from(context).inflate(
        r.layout.desklayout, null);
    this.addview(view);
  }

3.在activity中让它显示出来。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 取得系统窗体
mwindowmanager = (windowmanager) getapplicationcontext()
    .getsystemservice("window");
// 窗体的布局样式
mlayout = new windowmanager.layoutparams();
// 设置窗体显示类型——type_system_alert(系统提示)
mlayout.type = windowmanager.layoutparams.type_system_alert;
// 设置窗体焦点及触摸:
// flag_not_focusable(不能获得按键输入焦点)
mlayout.flags = windowmanager.layoutparams.flag_not_focusable;
// 设置显示的模式
mlayout.format = pixelformat.rgba_8888;
// 设置对齐的方法
mlayout.gravity = gravity.top | gravity.left;
// 设置窗体宽度和高度
mlayout.width = windowmanager.layoutparams.wrap_content;
mlayout.height = windowmanager.layoutparams.wrap_content;

详细 mainactivity 代码如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
package com.yc.yc_suspendingform;
import android.app.activity;
import android.graphics.pixelformat;
import android.graphics.rect;
import android.os.bundle;
import android.util.log;
import android.view.gravity;
import android.view.motionevent;
import android.view.view;
import android.view.view.onclicklistener;
import android.view.view.ontouchlistener;
import android.view.windowmanager;
import android.widget.button;
import com.yc.yc_floatingform.r;
public class mainactivity extends activity {
  private windowmanager mwindowmanager;
  private windowmanager.layoutparams mlayout;
  private desktoplayout mdesktoplayout;
  private long starttime;
  // 声明屏幕的宽高
  float x, y;
  int top;
  @override
  protected void oncreate(bundle savedinstancestate) {
    super.oncreate(savedinstancestate);
    setcontentview(r.layout.activity_main);   
    createwindowmanager();
    createdesktoplayout();
    button btn = (button) findviewbyid(r.id.btn);
    btn.setonclicklistener(new onclicklistener() {
      public void onclick(view v) {
        showdesk();
      }
    });
  }
  /**
   * 创建悬浮窗体
   */
  private void createdesktoplayout() {
    mdesktoplayout = new desktoplayout(this);
    mdesktoplayout.setontouchlistener(new ontouchlistener() {
      float mtouchstartx;
      float mtouchstarty;
      @override
      public boolean ontouch(view v, motionevent event) {
        // 获取相对屏幕的坐标,即以屏幕左上角为原点
        x = event.getrawx();
        y = event.getrawy() - top; // 25是系统状态栏的高度
        log.i("startp", "startx" + mtouchstartx + "====starty"
            + mtouchstarty);
        switch (event.getaction()) {
        case motionevent.action_down:
          // 获取相对view的坐标,即以此view左上角为原点
          mtouchstartx = event.getx();
          mtouchstarty = event.gety();
          log.i("startp", "startx" + mtouchstartx + "====starty"
              + mtouchstarty);
          long end = system.currenttimemillis() - starttime;
          // 双击的间隔在 300ms以下
          if (end < 300) {
            closedesk();
          }
          starttime = system.currenttimemillis();
          break;
        case motionevent.action_move:
          // 更新浮动窗口位置参数
          mlayout.x = (int) (x - mtouchstartx);
          mlayout.y = (int) (y - mtouchstarty);
          mwindowmanager.updateviewlayout(v, mlayout);
          break;
        case motionevent.action_up:
          // 更新浮动窗口位置参数
          mlayout.x = (int) (x - mtouchstartx);
          mlayout.y = (int) (y - mtouchstarty);
          mwindowmanager.updateviewlayout(v, mlayout);
          // 可以在此记录最后一次的位置
          mtouchstartx = mtouchstarty = 0;
          break;
        }
        return true;
      }
    });
  }
  @override
  public void onwindowfocuschanged(boolean hasfocus) {
    super.onwindowfocuschanged(hasfocus);
    rect rect = new rect();
    // /取得整个视图部分,注意,如果你要设置标题样式,这个必须出现在标题样式之后,否则会出错
    getwindow().getdecorview().getwindowvisibledisplayframe(rect);
    top = rect.top;//状态栏的高度,所以rect.height,rect.width分别是系统的高度的宽度
    log.i("top",""+top);
  }
  /**
   * 显示desktoplayout
   */
  private void showdesk() {
    mwindowmanager.addview(mdesktoplayout, mlayout);
    finish();
  }
  /**
   * 关闭desktoplayout
   */
  private void closedesk() {
    mwindowmanager.removeview(mdesktoplayout);
    finish();
  }
  /**
   * 设置windowmanager
   */
  private void createwindowmanager() {
    // 取得系统窗体
    mwindowmanager = (windowmanager) getapplicationcontext()
        .getsystemservice("window");
    // 窗体的布局样式
    mlayout = new windowmanager.layoutparams();
    // 设置窗体显示类型——type_system_alert(系统提示)
    mlayout.type = windowmanager.layoutparams.type_system_alert;
    // 设置窗体焦点及触摸:
    // flag_not_focusable(不能获得按键输入焦点)
    mlayout.flags = windowmanager.layoutparams.flag_not_focusable;
    // 设置显示的模式
    mlayout.format = pixelformat.rgba_8888;
    // 设置对齐的方法
    mlayout.gravity = gravity.top | gravity.left;
    // 设置窗体宽度和高度
    mlayout.width = windowmanager.layoutparams.wrap_content;
    mlayout.height = windowmanager.layoutparams.wrap_content;
  }
}

完整实例代码代码点击此处本站下载

希望本文所述对大家android程序设计有所帮助。