鸟语天空
WindowManager
post by:追风剑情 2016-8-8 14:25

Flags参数表示Window的属性,它有很多选项,通过这些选项可以控制Window的显示特性。
FLAG_NOT_FOCUSABLE: 表示Window不需要获取焦点,也不需要接收各种输入事件,此标记会同时启用FLAG_NOT_TOUCH_MODAL,最终事件会直接传递给下层的具有焦点的Window。
FLAG_NOT_TOUCH_MODAL: 在此模式下,系统会将当前Window区域以外的单击事件传递给底层的Window,当前Window区域以内的单击事件则自己处理。这个标记很重要,一般来说都需要开启此标记,否则其他Window将无法收到单击事件。
FLAG_SHOW_WHEN_LOCKED: 开启此模式可以让Window显示在锁屏的界面上。

Type参数表示Window的类型,Window有三种类型,分别是应用Window、子Window和系统Window。应用类Window对应着一个Activity。子Window不能单独存在,它需要附属在特定的父Window之中,比如常见的一些Dialog就是一个子Window。系统Window是需要声明权限才能创建的Window,比如Toast 和系统状态栏这些都是系统Window。Window是分层的,每个Window都有对应的z-ordered,层级大的会覆盖在层级小的Window的上面,这和HTML中的z-index的概念是完全一致的。在三类Window中,应用Window的层级范围是1-99,子Window的层级范围是1000-1999,系统Window的层级范围是2000-2999,这些层级范围对应着WindowManager.LayoutParams的type参数。如果想要Window位于所有Window的最顶层,那么采用较大的层级即可。很显然系统Window的层级是最大的,而且系统层级有很多值,一般我们可以选用TYPE_SYSTEM_OVERLAY或者TYPE_SYSTEM_ERROR,如果采用TYPE_SYSTEM_ERROR,只需要为type参数指定这个层级即可:
mLayoutParams.flags = WindowManager.LayoutParams.TYPE_SYSTEM_ERROR;
同时声明权限:
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
因为系统类型的Window是需要检查权限的,如果不在AndroidManifest中使用相应的权限,那么创建Window的时候就会报错。
Caused by: android.view.WindowManager$BadTokenException: Unable to add window android.view.ViewRootImpl$W@26079204 -- permission denied for this window type

WindowManager所提供的功能很简单,常用的只有三个功方法,即添加View、更新View和删除View,这三个方法定义在ViewManager中,而WindowManager继承了ViewManager

注意:MIUI系统需要在设置->其他应用管理->应用信息->权限管理,中打开“显示悬浮窗”才能显示。

222222.png

 

示例代码:

package com.test.androidtest;

import java.io.File;
import java.io.FileFilter;
import java.util.regex.Pattern;

import android.support.v4.app.Fragment;
import android.app.Activity;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Vibrator;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.ContextThemeWrapper;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager.NameNotFoundException;
import android.graphics.PixelFormat;
import android.provider.Settings;

public class MainActivity extends Activity {

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.fragment_main);
		
		//创建一个Window
		Button mFloatingButton = new Button(this);
		mFloatingButton.setText("悬浮按钮");
		WindowManager.LayoutParams mLayoutParams = new WindowManager.LayoutParams(
				LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, 0, 0,
				PixelFormat.TRANSPARENT);
		mLayoutParams.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;
		mLayoutParams.format = PixelFormat.RGBA_8888;//设置背景透明
		mLayoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
				| WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
				| WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED;
		mLayoutParams.gravity = Gravity.LEFT | Gravity.TOP;
		mLayoutParams.x = 500;
		mLayoutParams.y = 500;
		
		WindowManager mWindowManager = (WindowManager)getSystemService(Context.WINDOW_SERVICE);
		mWindowManager.addView(mFloatingButton, mLayoutParams);
	}
}

 

运行截图

1111111.png

 

评论:
发表评论:
昵称

邮件地址 (选填)

个人主页 (选填)

内容