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>
参考文档
历史上的今天
暂无评论...
随机推荐
Android动画之TranslateAnimation使用
Android动画View Animation 视图动画(Tween Animation 补间动画),只能用来设置View的动画Drawable Animation 帧动画(Frame动画),一帧帧地显示资源文件中的DrawableProperty Animation 属性动画,在andr...
胡适:赠与今年的大学毕业生
这一两个星期里,各地的大学都有毕业的班次,都有很多的毕业生离开学校去开始他们的成人事业。学生的生活是一种享有特殊优待的生活,不妨幼稚一点,不妨吵吵闹闹,社会都能纵容他们,不肯严格的要他们负行为的责任。现在他们要撑起自己的肩膀来挑他们自己的担子了。在这个国难最紧急的年头,他们的担子真不轻! 我们祝他们...
[摘]SeekBar的thumbOffset属性
Android的控件SeekBar中有个android:thumbOffset的属性,这个属性的作用是指示thumb(滑块)在拖动条的进度最大值与最小值时相对于拖动条的偏移量。thumbOffset值1、thumbOffset:0px最小值时thumb位置:thumb的最左端与SeekBar的...
修改Android系统时间设置到2099
前言修改Android支持的时间大于2037。系统时间限制默认是Int(有符号32位,最大0X7FFFFFFF)最大值即为: Integer.MAX_VALUE = 0X7FFFFFFF=2147483647 = 2038-01-19 11:14:07。个人流水账而已。正文将RTC时间限...
Android新增开关安装apk选项
前言记录一下,Android中设置一个开关进行判断是否允许用户自己安装apk。记录于此,方便自己查阅。正文frameworks/base/services/core/java/com/android/server/pm/PackageInstallerService.java@Overr...
[代码片段]GradientTextView渐变的TextView
前言本质上就是通过LinearGradient来实现渐变的正文public class GradientTextView extends androidx.appcompat.widget.AppCompatTextView { public GradientTextView(Context...