WindowManager主要用来管理窗口的一些状态、屏幕分辨率、属性、view增加、删除、更新、窗口顺序、消息收集和处理等。其继承于ViewManager,获取这个对象有两种方式:

1、Activity.getWindowManager();

2、(WindowManager)Context.getSystemService(Context.Window_SERVICE);

其中有主要用到3个方法:

1、添加窗口

public void addView(View view, ViewGroup.LayoutParams params);

2、删除窗口

public void removeView(View view);

3、更新窗口

public void updateViewLayout(View view, ViewGroup.LayoutParams params);

还可以利用WindowManager获取屏幕的分辨率:

// 屏幕的宽度wManager = contextActivity.getWindowManager();DisplayMetrics dm = new DisplayMetrics();wManager.getDefaultDisplay().getMetrics(dm);//屏幕宽度screenWith = dm.widthPixels;//屏幕高度screenheigt=dm.heightPixels;

其内部有一个静态类,windowManager.LayoutParams,这个类可以设置窗口的各种属性,下面对这个类做一下介绍。

继承关系 :
java.lang.Object
   ↳android.view.ViewGroup.LayoutParams
       ↳android.view.WindowManager.LayoutParams

各种属性:

1.public int x; 如果忽略gravity属性,那么它表示窗口的绝对X位置。   什么是gravity属性呢?简单地说,就是窗口如何停靠。  当设置了 Gravity.LEFT 或 Gravity.RIGHT 之后,x值就表示到特定边的距离。

2. public int y; 如果忽略gravity属性,那么它表示窗口的绝对Y位置。 当设置了 Gravity.TOP 或 Gravity.BOTTOM 之后,y值就表示到特定边的距离。

3. public float horizontalWeight; public float verticalWeight; 在纵/横向上,为关联的view预留了多少扩展空间(像素)。如果是0,那么此view不能被拉伸。

   其他情况下,扩展空间(像素)将被widget所均分。
4.public int type;
窗口类型。有3种主要类型:
Applicationwindows:
        取值在 FIRST_APPLICATION_WINDOW 和 LAST_APPLICATION_WINDOW 之间。 是通常的、顶层的应用程序窗口。必须将 token 设置成 activity 的 token 。
Sub_windows:
        取值在 FIRST_SUB_WINDOW 和 LAST_SUB_WINDOW 之间。  与顶层窗口相关联,token 必须设置为它所附着的宿主窗口的 token。
Systemwindows:
        取值在 FIRST_SYSTEM_WINDOW 和 LAST_SYSTEM_WINDOW 之间。 用于特定的系统功能。它不能用于应用程序,使用时需要特殊权限。

 


下面定义了 type 的取值:

      应用程序窗口。
      public static final int FIRST_APPLICATION_WINDOW = 1;
      所有程序窗口的“基地”窗口,其他应用程序窗口都显示在它上面。     
      public static final int TYPE_BASE_APPLICATION   =1;       
      普通应哟功能程序窗口。token必须设置为Activity的token,以指出该窗口属谁。
      public static final int TYPE_APPLICATION       = 2;
       用于应用程序启动时所显示的窗口。应用本身不要使用这种类型。
      它用于让系统显示些信息,直到应用程序可以开启自己的窗口。   
      public static final int TYPE_APPLICATION_STARTING = 3;   
     应用程序窗口结束。
      public static final int LAST_APPLICATION_WINDOW = 99;
      子窗口。子窗口的Z序和坐标空间都依赖于他们的宿主窗口。
      public static final int FIRST_SUB_WINDOW       = 1000;
      面板窗口,显示于宿主窗口上层。
      public static final int TYPE_APPLICATION_PANEL  = FIRST_SUB_WINDOW;
      媒体窗口,例如视频。显示于宿主窗口下层。
      public static final int TYPE_APPLICATION_MEDIA  = FIRST_SUB_WINDOW+1;
      应用程序窗口的子面板。显示于所有面板窗口的上层。(GUI的一般规律,越“子”越靠上)
      public static final int TYPE_APPLICATION_SUB_PANEL = FIRST_SUB_WINDOW +2;
      对话框。类似于面板窗口,绘制类似于顶层窗口,而不是宿主的子窗口。
      public static final int TYPE_APPLICATION_ATTACHED_DIALOG = FIRST_SUB_WINDOW +3;
      媒体信息。显示在媒体层和程序窗口之间,需要实现透明(半透明)效果。(例如显示字幕)
      public static final int TYPE_APPLICATION_MEDIA_OVERLAY  = FIRST_SUB_WINDOW +4;
      子窗口结束。( End of types of sub-windows )
      public static final int LAST_SUB_WINDOW        = 1999;
      系统窗口。非应用程序创建。
     public static final int FIRST_SYSTEM_WINDOW    = 2000;
      状态栏。只能有一个状态栏;它位于屏幕顶端,其他窗口都位于它下方。
     public static final int TYPE_STATUS_BAR        =  FIRST_SYSTEM_WINDOW;
      搜索栏。只能有一个搜索栏;它位于屏幕上方。
      public static final int TYPE_SEARCH_BAR        = FIRST_SYSTEM_WINDOW+1;
      电话窗口。它用于电话交互(特别是呼入)。它置于所有应用程序之上,状态栏之下。
      public static final int TYPE_PHONE            = FIRST_SYSTEM_WINDOW+2;
      系统提示。它总是出现在应用程序窗口之上。
      public static final int TYPE_SYSTEM_ALERT      =  FIRST_SYSTEM_WINDOW +3;
      锁屏窗口。
      public static final int TYPE_KEYGUARD          = FIRST_SYSTEM_WINDOW +4;
      信息窗口。用于显示toast。
      public static final int TYPE_TOAST            = FIRST_SYSTEM_WINDOW +5;
      系统顶层窗口。显示在其他一切内容之上。此窗口不能获得输入焦点,否则影响锁屏。
      public static final int TYPE_SYSTEM_OVERLAY    =  FIRST_SYSTEM_WINDOW +6;
      电话优先,当锁屏时显示。此窗口不能获得输入焦点,否则影响锁屏。
      public static final int TYPE_PRIORITY_PHONE    =  FIRST_SYSTEM_WINDOW +7;
      系统对话框。(例如音量调节框)。
      public static final int TYPE_SYSTEM_DIALOG     =  FIRST_SYSTEM_WINDOW +8;
      锁屏时显示的对话框。
      public static final int TYPE_KEYGUARD_DIALOG   =  FIRST_SYSTEM_WINDOW +9;
      系统内部错误提示,显示于所有内容之上。
      public static final int TYPE_SYSTEM_ERROR      =  FIRST_SYSTEM_WINDOW +10;
      内部输入法窗口,显示于普通UI之上。应用程序可重新布局以免被此窗口覆盖。
      public static final int TYPE_INPUT_METHOD      =  FIRST_SYSTEM_WINDOW +11;
      内部输入法对话框,显示于当前输入法窗口之上。
      public static final int TYPE_INPUT_METHOD_DIALOGFIRST_SYSTEM_WINDOW +12;
      墙纸窗口。 public static final int TYPE_WALLPAPER         = FIRST_SYSTEM_WINDOW +13;
      状态栏的滑动面板。 public static final int TYPE_STATUS_BAR_PANEL   = FIRST_SYSTEM_WINDOW +14;
      系统窗口结束。    
 public static final int LAST_SYSTEM_WINDOW     = 2999;





在工作中做一款游戏SDK,里面有一个效果就是有一个悬浮按钮浮在游戏上面,点击可以弹出一个框,在框里有两个按钮,点击按钮可以进入对应的条目,这个我就是用的windowmanager实现的,先来上个效果图:



给这个类的代码贴一下吧,源码就不给了,~~~~~~~~~

扫描关注我的微信公众号:


public class FloatingViewController {private Button bbsBtn, hideBtn;private TextView bbsTV, hideTV;private LinearLayout containerLayout;private WindowManager.LayoutParams wmParams;private WindowManager.LayoutParams wmcParams;private WindowManager wManager;// 当前手指所在屏幕中的坐标private float xInScreen;private float yInScreen;private float xScreen;private float yScreen;private int loacation[] = new int[] { 0, 0 };// 窗口中的位置的坐标private float xInView;private float yInView;private Button circleButton;private int screenWidth = 0;private static float screenScale = 0;private int statusBarHeight;private int viewLength = 0;private int screenWith;private SharedPreferences locationPreferences;private static int count;private static Activity contextActivity;private FloatingViewController() {}private static FloatingViewController fvc;public static FloatingViewController getInstance(Activity context) {count++;contextActivity = context;if (fvc == null) {fvc = new FloatingViewController();}return fvc;}public void show() {if (count > 1) {return;}wManager = contextActivity.getWindowManager();Display display = wManager.getDefaultDisplay();screenWith = display.getWidth();wmParams = new WindowManager.LayoutParams();wmParams.format = PixelFormat.RGBA_8888;wmParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;wmParams.gravity = Gravity.LEFT | Gravity.TOP;wmParams.type = WindowManager.LayoutParams.TYPE_APPLICATION;circleButton = new Button(contextActivity);screenWidth = new SizeUtils(contextActivity).sysWidth;if (screenScale == 0) {if (new SizeUtils(contextActivity).screenHeightScale < new SizeUtils(contextActivity).screenWidthScale)screenScale = new SizeUtils(contextActivity).screenHeightScale;else {screenScale = new SizeUtils(contextActivity).screenWidthScale;}}viewLength = (int) (235 * screenScale);circleButton.setBackgroundDrawable(contextActivity.getResources().getDrawable(MResource.getIdByName(contextActivity, "drawable","overlay_logo")));circleButton.setOnTouchListener(new View.OnTouchListener() {@Overridepublic boolean onTouch(View v, MotionEvent event) {switch (event.getAction()) {case MotionEvent.ACTION_DOWN:xInView = event.getX();yInView = event.getY();xScreen = event.getRawX();yScreen = event.getRawY() - getStatusBarHeight();Log.e("按下", xScreen + "按下" + yScreen);break;case MotionEvent.ACTION_MOVE:if (containerLayout != null)containerLayout.setVisibility(View.INVISIBLE);xInScreen = event.getRawX();yInScreen = event.getRawY() - getStatusBarHeight();updateViewPosition();Log.e("移动", "移动");break;case MotionEvent.ACTION_UP:Log.e("触摸弹起", xInScreen + "触摸弹起" + yInScreen);xInScreen = event.getRawX();yInScreen = event.getRawY() - getStatusBarHeight();if (xInScreen <= screenWith / 2) {// 图标icon吸附在左边wmParams.x = 0;} else {// 图标icon吸附在右边wmParams.x = screenWith;}if (Math.abs(xInScreen - xScreen) < 5&& Math.abs(yInScreen - yScreen) < 5) {circleButton.getLocationOnScreen(loacation);int viewRight = screenWidth- (wmParams.x + wmParams.width / 2);int viewLeft = wmParams.x;if (viewLeft > viewLength && containerLayout == null) {openLeftBigWindow();} else if (viewRight > viewLength&& containerLayout == null) {openRightBigWindow();} elseremoveBigWindow();}wManager.updateViewLayout(circleButton, wmParams);Editor editor = locationPreferences.edit();editor.putFloat("x", (int) xInScreen);editor.putFloat("y", (int) yInScreen);editor.commit();}return false;}});wmParams.width = wmParams.height = (int) (60 * screenScale);locationPreferences = contextActivity.getPreferences(android.content.Context.MODE_PRIVATE);xInScreen = locationPreferences.getFloat("x", new SizeUtils(contextActivity).sysWidth);yInScreen = locationPreferences.getFloat("y", new SizeUtils(contextActivity).sysHeight / 2);xInView = 60;yInView = 60;wmParams.x = 0;wmParams.y = (int) yInScreen;wManager.addView(circleButton, wmParams);// updateViewPosition();}private void updateViewPosition() {wmParams.x = (int) (xInScreen - xInView);wmParams.y = (int) (yInScreen - yInView);wManager.updateViewLayout(circleButton, wmParams);Editor editor = locationPreferences.edit();editor.putFloat("x", (int) xInScreen);editor.putFloat("y", (int) yInScreen);editor.commit();}protected void openLeftBigWindow() {if (wmcParams == null) {wmcParams = new WindowManager.LayoutParams();wmcParams.format = PixelFormat.RGBA_8888;wmcParams.type = WindowManager.LayoutParams.TYPE_APPLICATION;wmcParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;wmcParams.gravity = Gravity.LEFT | Gravity.TOP;wmcParams.x = (int) (loacation[0] - viewLength);wmcParams.y = (int) (wmParams.y);wmcParams.width = WindowManager.LayoutParams.WRAP_CONTENT;wmcParams.height = WindowManager.LayoutParams.WRAP_CONTENT;containerLayout = new LinearLayout(contextActivity);containerLayout.setBackgroundResource(MResource.getIdByName(contextActivity, "drawable", "overlay_lift"));bbsTV = new TextView(contextActivity);bbsTV.setText("账户");bbsTV.setTextColor(Color.WHITE);hideTV = new TextView(contextActivity);hideTV.setText("隐藏");hideTV.setTextColor(Color.WHITE);hideBtn = new Button(contextActivity);hideBtn.setBackgroundResource(MResource.getIdByName(contextActivity, "drawable", "overlay_hide"));hideBtn.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {AnimationSet set = new AnimationSet(true);set.addAnimation(new ScaleAnimation(1f, 1.5f, 1f, 1.5f));set.setDuration(300);set.setInterpolator(new AnticipateOvershootInterpolator(9F));count = 0;hideBtn.startAnimation(set);hideTV.startAnimation(set);removeAllWindow();}});bbsBtn = new Button(contextActivity);bbsBtn.setBackgroundResource(MResource.getIdByName(contextActivity,"drawable", "overlay_account"));bbsBtn.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {AnimationSet set = new AnimationSet(true);set.addAnimation(new ScaleAnimation(1f, 1.2f, 1f, 1.2f));set.setDuration(300);set.setInterpolator(new AnticipateOvershootInterpolator(9f));set.setInterpolator(new BounceInterpolator());bbsBtn.startAnimation(set);bbsTV.startAnimation(set);if (containerLayout != null)containerLayout.setVisibility(View.INVISIBLE);Intent intent = new Intent(contextActivity,AccountActivity.class);contextActivity.startActivity(intent);}});containerLayout.setLayoutParams(new LinearLayout.LayoutParams(256,60));containerLayout.setPadding(10, 10, 10, 10);containerLayout.setGravity(Gravity.CENTER_VERTICAL);LinearLayout.LayoutParams bbsLayoutParams = new LinearLayout.LayoutParams(40, 40);bbsLayoutParams.setMargins(0, 0, 0, 0);// LayoutParams homeParams = new LinearLayout.LayoutParams(60, 60);LinearLayout.LayoutParams textParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,LinearLayout.LayoutParams.WRAP_CONTENT);textParams.setMargins(10, 0, 0, 0);LinearLayout.LayoutParams hideTextLayoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,LinearLayout.LayoutParams.WRAP_CONTENT);hideTextLayoutParams.setMargins(10, 0, 0, 0);LinearLayout.LayoutParams hideLayoutParams = new LinearLayout.LayoutParams(40, 40);hideLayoutParams.setMargins(20, 0, 0, 0);bbsBtn.setLayoutParams(bbsLayoutParams);hideBtn.setLayoutParams(hideLayoutParams);bbsTV.setLayoutParams(textParams);hideTV.setLayoutParams(hideTextLayoutParams);containerLayout.addView(bbsBtn);containerLayout.addView(bbsTV);containerLayout.addView(hideBtn);containerLayout.addView(hideTV);RelayoutViewTool.relayoutViewWithScale(containerLayout, screenScale);wManager.addView(containerLayout, wmcParams);} else {removeBigWindow();}}protected void openRightBigWindow() {if (wmcParams == null) {wmcParams = new WindowManager.LayoutParams();wmcParams.format = PixelFormat.RGBA_8888;wmcParams.type = WindowManager.LayoutParams.TYPE_APPLICATION;wmcParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;wmcParams.gravity = Gravity.LEFT | Gravity.TOP;Log.e("test", wmcParams.width + "--wmcparm");wmcParams.x = (int) (loacation[0] + wmParams.width);wmcParams.y = (int) (wmParams.y);Log.e("wmcParams", wmParams.x + "vs" + wmParams.y + "("+ wmcParams.x + "--" + wmcParams.y + ")");wmcParams.width = WindowManager.LayoutParams.WRAP_CONTENT;wmcParams.height = WindowManager.LayoutParams.WRAP_CONTENT;containerLayout = new LinearLayout(contextActivity);containerLayout.setBackgroundResource(MResource.getIdByName(contextActivity, "drawable", "overlay_right"));bbsTV = new TextView(contextActivity);bbsTV.setText("账户");bbsTV.setTextColor(Color.WHITE);hideTV = new TextView(contextActivity);hideTV.setText("隐藏");hideTV.setTextColor(Color.WHITE);hideBtn = new Button(contextActivity);hideBtn.setBackgroundResource(MResource.getIdByName(contextActivity, "drawable", "overlay_hide"));hideBtn.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {AnimationSet set = new AnimationSet(true);set.addAnimation(new ScaleAnimation(1f, 1.5f, 1f, 1.5f));set.setDuration(300);set.setInterpolator(new AnticipateOvershootInterpolator(9F));// set.setInterpolator(new BounceInterpolator());hideBtn.startAnimation(set);hideTV.startAnimation(set);count = 0;removeAllWindow();}});bbsBtn = new Button(contextActivity);bbsBtn.setBackgroundResource(MResource.getIdByName(contextActivity,"drawable", "overlay_account"));bbsBtn.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {AnimationSet set = new AnimationSet(true);set.addAnimation(new ScaleAnimation(1f, 1.2f, 1f, 1.2f));set.setDuration(300);set.setInterpolator(new AnticipateOvershootInterpolator(9f));set.setInterpolator(new BounceInterpolator());bbsBtn.startAnimation(set);bbsTV.startAnimation(set);if (containerLayout != null)containerLayout.setVisibility(View.INVISIBLE);Intent intent = new Intent(contextActivity,AccountActivity.class);contextActivity.startActivity(intent);}});containerLayout.setLayoutParams(new LinearLayout.LayoutParams(256,60));containerLayout.setPadding(10, 10, 10, 10);containerLayout.setGravity(Gravity.CENTER_VERTICAL);LinearLayout.LayoutParams bbsLayoutParams = new LinearLayout.LayoutParams(40, 40);bbsLayoutParams.setMargins(20, 0, 0, 0);// LayoutParams homeParams = new LinearLayout.LayoutParams(60, 60);LinearLayout.LayoutParams textParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,LinearLayout.LayoutParams.WRAP_CONTENT);textParams.setMargins(10, 0, 0, 0);LinearLayout.LayoutParams hideTextLayoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,LinearLayout.LayoutParams.WRAP_CONTENT);hideTextLayoutParams.setMargins(10, 0, 0, 0);LinearLayout.LayoutParams hideLayoutParams = new LinearLayout.LayoutParams(40, 40);hideLayoutParams.setMargins(20, 0, 0, 0);bbsBtn.setLayoutParams(bbsLayoutParams);hideBtn.setLayoutParams(hideLayoutParams);bbsTV.setLayoutParams(textParams);hideTV.setLayoutParams(hideTextLayoutParams);containerLayout.addView(bbsBtn);containerLayout.addView(bbsTV);containerLayout.addView(hideBtn);containerLayout.addView(hideTV);RelayoutViewTool.relayoutViewWithScale(containerLayout, screenScale);wManager.addView(containerLayout, wmcParams);} else {removeBigWindow();}}protected void removeBigWindow() {if (containerLayout != null && wmcParams != null) {wManager.removeView(containerLayout);containerLayout = null;wmcParams = null;}// if(containerLayout==null){// wManager.removeView(containerLayout);//// }}public void removeAllWindow() {removeBigWindow();wManager.removeView(circleButton);circleButton = null;wManager = null;fvc = null;}private int getStatusBarHeight() {if (statusBarHeight == 0) {try {@SuppressWarnings("rawtypes")Class c = Class.forName("com.android.internal.R$dimen");try {Object o = c.newInstance();try {Field field = c.getField("status_bar_height");int x = field.getInt(o);statusBarHeight = contextActivity.getResources().getDimensionPixelSize(x);} catch (NoSuchFieldException e) {// TODO Auto-generated catch blocke.printStackTrace();}} catch (InstantiationException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IllegalAccessException e) {// TODO Auto-generated catch blocke.printStackTrace();}} catch (ClassNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace();}}return statusBarHeight;}public void destroyFloat() {if (containerLayout != null) {count=0;removeAllWindow();}//if (containerLayout == null&&circleButton != null) {//wManager.removeView(circleButton);//circleButton = null;//wManager = null;//fvc = null;//}if (fvc != null) {count = 0;removeAllWindow();}}}



更多相关文章

  1. 显示gif动画(帧动画的播放)
  2. 取消程序在最近六项中显示以及直接调用信息短信界面
  3. [译]Android架构组件 – 查看Room和LiveData – 第一部分
  4. android 笔记---开机启动Service或Activity
  5. Android提高第四篇之Activity+Intent
  6. 转Android(安卓)安全攻防(三): SEAndroid(安卓)Zygote执行用户态许
  7. Android系统的开机画面显示过程分析(8)
  8. Android(安卓)Studio 常用控件和常用布局的介绍
  9. Android-EditText属性大全

随机推荐

  1. 如何从其他dtypes创建一个numpy dtype?
  2. 独立于数据库的MAX()函数在SQLAlchemy中
  3. 使用python api递归计算每个Dropbox文件
  4. Python为8bit深度图像应用color map
  5. 可变序列长度数据的分类
  6. 'str'对象不能解释为groupby上的整数
  7. 基于Python的XSS测试工具XSStrike使用方
  8. 乘客的Django应用程序显示空主页
  9. 如何用所有可能的方式将一个列表分割成对
  10. 安装:Ubuntu12.04+Python3+Django1.7.9过