WindowManager介绍
通过Context.getSystemService(Context.WINDOW_SERVICE)可以获得 WindowManager对象。
使用WindowManager可以在其他应用最上层,甚至手机桌面最上层显示窗口。
调用的是WindowManager继承自基类的addView方法和removeView方法来显示和隐藏窗口。
LayoutParams常用参数:
- type值
用于确定悬浮窗的类型,一般设为2002,表示在所有应用程序之上,但在状态栏之下。
- flags值
用于确定悬浮窗的行为,比如说不可聚焦,非模态对话框等等,属性非常多,大家可以查看文档。
- gravity值
用于确定悬浮窗的对齐方式,一般设为左上角对齐,这样当拖动悬浮窗的时候方便计算坐标。
- x值
用于确定悬浮窗的位置,如果要横向移动悬浮窗,就需要改变这个值。
- y值
用于确定悬浮窗的位置,如果要纵向移动悬浮窗,就需要改变这个值。
- width值
用于指定悬浮窗的宽度。
- height值
用于指定悬浮窗的高度。
WindowManager实现悬浮窗
声明权限
AndroidManifest.xml中添加如下代码
<!-- 显示顶层浮窗 --> <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
注意:
Android 6.0以上【非系统应用】,需要在[系统设置]找到[应用和通知]已经的[我们的应用],然后点击进入[高级],打开[在应用上方显示]开关
demo代码片段
MainActivity.java
public class WindowActivity extends Activity { private String TAG = getClass().getSimpleName(); private WindowManager windowManager; private WindowManager.LayoutParams mLayoutParams = null; private View seekbarLayoutView = null; private boolean hasWindow = false; private LayoutInflater inflater = null; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); Log.d(TAG, "onCreate : "); setContentView(R.layout.activity_main); initUI(); initWindow(); } @Override protected void onResume() { super.onResume(); Log.d(TAG, "onResume: "); } @Override protected void onPause() { super.onPause(); Log.d(TAG, "onPause: "); } @Override protected void onStop() { super.onStop(); Log.d(TAG, "onStop: "); } @Override protected void onDestroy() { super.onDestroy(); Log.d(TAG, "onDestroy: "); } private void initUI() { findViewById(R.id.main_bt_one).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Log.d(TAG, "onClick show(): "); show(); } }); return; } private void initWindow() { inflater = LayoutInflater.from(getApplicationContext()); windowManager = (WindowManager) getSystemService(Context.WINDOW_SERVICE); mLayoutParams = new WindowManager.LayoutParams(); //设置透明度 mLayoutParams.alpha = 1.0f; //Android 6.0后,非系统应用,需要在[系统设置]找到[应用和通知]已经的[我们的应用],然后点击进入[高级],打开[在应用上方显示]开关 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {//6.0 以上 mLayoutParams.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY; } else { mLayoutParams.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT; } mLayoutParams.flags = WindowManager.LayoutParams.FLAG_FULLSCREEN; mLayoutParams.width = ViewGroup.LayoutParams.MATCH_PARENT; mLayoutParams.height = ViewGroup.LayoutParams.MATCH_PARENT; seekbarLayoutView = inflater.inflate(R.layout.topbar_layout, null); seekbarLayoutView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Log.d(TAG, "onClick hide(): "); hide(); } }); return; } private void show() { Log.d(TAG, "show hasWindow : " + hasWindow); if (null != windowManager && (null != seekbarLayoutView) && (seekbarLayoutView.getParent() == null) && !hasWindow) { hasWindow = true; windowManager.addView(seekbarLayoutView, mLayoutParams); } return; } private void hide() { Log.d(TAG, "hide hasWindow : " + hasWindow); if (null != windowManager && (null != seekbarLayoutView) && hasWindow) { windowManager.removeView(seekbarLayoutView); hasWindow = false; } return; }
activity_main.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center" android:background="@android:color/darker_gray" android:orientation="vertical"> <Button android:id="@+id/main_bt_one" android:layout_width="match_parent" android:layout_height="60dp" android:gravity="center" android:text="one" /> </LinearLayout>
topbar_layout.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@android:color/holo_green_dark" android:paddingTop="160dp" tools:ignore="MissingDefaultResource"> </RelativeLayout>
参考文档
历史上的今天
暂无评论...
随机推荐
王小波:人为什么活着
银河,你好!我在家里给你写信。你问我人为什么活着,我哪能知道啊?我又不是牧师。释迦牟尼为了解决这个问题出了家,结果得到的结论是人活着为了涅,就是死。这简直近乎开玩笑了。不过活着总得死,这一点是不错的,我有时对这一点也很不满意呢。还有人活着有时候有点闷,这也是很不愉快的。过去我想,人活着都得为别人...
Glide V4和V3 使用不同
Glide是目前 Android 上最流行的图片加载库之一。目前Glide已经更新到了4.11.0repositories { mavenCentral() google()}dependencies { implementation 'com.github.bumptech...
ADB更改系统设置中的参数
Android4.2以后的源码android-17\com\android\commands目录下较之前的版本多了一个settings命令,查看其中的SettingsCmd.java文件,末尾有命令的帮助信息:private static void printUsage() { ...
Android P去除MediaProvider编译
前言记录一下Android P去除MediaProvider编译。记录于此,方便自己查阅。正文隐藏内容!付费阅读后才能查看!¥1 ¥3多个隐藏块只需支付一次付费阅读参考文章
丰子恺:渐
不为“渐”所迷,不为造物所欺,而收缩无限的时间并空间于方寸的心中。故佛家能纳须弥于芥子。使人生圆滑进行的微妙的要素,莫如“渐”;造物主骗人的手段,也莫如“渐”。在不知不觉之中,天真烂漫的孩子“渐渐”变成野心勃勃的青年;慷慨豪侠的青年“渐渐”变成冷酷的成人;血气旺盛的成人“渐渐”变成顽固的老头子。因为...
内存分析工具MAT简单记录
前言MAT(Memory Analyzer Tool,一个基于Eclipse的内存分析工具,是一个快速、功能丰富的JAVA heap分析工具,它可以帮助我们查找内存泄漏和减少内存消耗。使用内存分析工具从众多的对象中进行分析,快速的计算出在内存中对象的占用大小,看看是谁阻止了垃圾收集器的回收工作,...