服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - Android - Android实现悬浮窗体效果

Android实现悬浮窗体效果

2022-08-30 13:44叶超Luka Android

这篇文章主要为大家详细介绍了Android实现悬浮窗体效果,显示悬浮窗口,窗口可以拖动,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

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

Android实现悬浮窗体效果

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

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

?
1
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />

2.悬浮窗口布局实现

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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
18
19
20
21
22
23
// 取得系统窗体
 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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
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实现悬浮窗体效果

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。

原文链接:http://www.cnblogs.com/yc-755909659/p/4281214.html

延伸 · 阅读

精彩推荐