用过手机360和QQ手机管家等一些软件的朋友,会发现,在这些应用中,会出现一个悬浮窗体,例如QQ手机管家中打电话的场景:

这种窗体除了会显示外,还可以移动它的位置,并且一直显示。除了关闭当前程序外,窗口不会主动消失。其实,它的使用原理也很简单,就是借用了WindowManager这个管理类来实现的。
注意:要在AndroidManifest.xml中添加使用权限:

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

这里,我采用代码布局的方式,模仿了一下QQ这个界面效果:

  1. import android.content.Context;
  2. import android.widget.ImageView;
  3. import android.widget.LinearLayout;
  4. import android.widget.TextView;
  5. public class DesktopLayout extends LinearLayout {
  6. public DesktopLayout(Context context) {
  7. super(context);
  8. setOrientation(LinearLayout.HORIZONTAL);
  9. LayoutParams mLayoutParams = new LayoutParams(
  10. LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
  11. setLayoutParams(mLayoutParams);
  12. // 显示的ICON
  13. ImageView mImageView = new ImageView(context);
  14. mImageView.setImageResource(R.drawable.icon);
  15. addView(mImageView, mLayoutParams);
  16. // 显示的文字
  17. TextView mTextView = new TextView(context);
  18. mTextView.setText("Hello");
  19. mTextView.setTextSize(30);
  20. addView(mTextView, mLayoutParams);
  21. }
  22. }

接下来,在activity中让它显示出来。首先要设置一下WindowManager.LayoutParams:

  1. // 取得系统窗体
  2. mWindowManager = (WindowManager) getApplicationContext()
  3. .getSystemService("window");
  4. // 窗体的布局样式
  5. mLayoutParams = new WindowManager.LayoutParams();
  6. // 设置窗体显示类型——TYPE_SYSTEM_ALERT(系统提示)
  7. mLayoutParams.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;
  8. // 设置窗体焦点及触摸:
  9. // FLAG_NOT_FOCUSABLE(不能获得按键输入焦点)
  10. mLayoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
  11. // 设置显示的模式
  12. mLayoutParams.format = PixelFormat.RGBA_8888;
  13. // 设置对齐的方法
  14. mLayoutParams.gravity = Gravity.TOP | Gravity.LEFT;
  15. // 设置窗体宽度和高度
  16. mLayoutParams.width = WindowManager.LayoutParams.WRAP_CONTENT;
  17. mLayoutParams.height = WindowManager.LayoutParams.WRAP_CONTENT;
  18. // 设置窗体显示的位置,否则在屏幕中心显示
  19. mLayoutParams.x = 50;
  20. mLayoutParams.y = 50;

显示窗体与关闭窗体的方法:

  1. mWindowManager.addView(mDesktopLayout, mLayoutParams);
  2. mWindowManager.removeView(mDesktopLayout);

以下是activity的原代码,这里设计了一个双击关闭窗体的效果:

  1. import android.app.Activity;
  2. import android.graphics.PixelFormat;
  3. import android.os.Bundle;
  4. import android.view.Gravity;
  5. import android.view.MotionEvent;
  6. import android.view.View;
  7. import android.view.View.OnClickListener;
  8. import android.view.View.OnTouchListener;
  9. import android.view.WindowManager;
  10. import android.widget.Button;
  11. public class DeskTip extends Activity {
  12. private WindowManager mWindowManager;
  13. private WindowManager.LayoutParams mLayoutParams;
  14. private DesktopLayout mDesktopLayout;
  15. private long starttime;
  16. /**
  17. * 创建悬浮窗体
  18. */
  19. private void createDesktopLayout() {
  20. mDesktopLayout = new DesktopLayout(this);
  21. mDesktopLayout.setOnTouchListener(new OnTouchListener() {
  22. public boolean onTouch(View v, MotionEvent event) {
  23. onActionMove(event);
  24. return true;
  25. }
  26. });
  27. }
  28. /**
  29. * 设置WindowManager
  30. */
  31. private void createWindowManager() {
  32. // 取得系统窗体
  33. mWindowManager = (WindowManager) getApplicationContext()
  34. .getSystemService("window");
  35. // 窗体的布局样式
  36. mLayoutParams = new WindowManager.LayoutParams();
  37. // 设置窗体显示类型——TYPE_SYSTEM_ALERT(系统提示)
  38. mLayoutParams.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;
  39. // 设置窗体焦点及触摸:
  40. // FLAG_NOT_FOCUSABLE(不能获得按键输入焦点)
  41. mLayoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
  42. // 设置显示的模式
  43. mLayoutParams.format = PixelFormat.RGBA_8888;
  44. // 设置对齐的方法
  45. mLayoutParams.gravity = Gravity.TOP | Gravity.LEFT;
  46. // 设置窗体宽度和高度
  47. mLayoutParams.width = WindowManager.LayoutParams.WRAP_CONTENT;
  48. mLayoutParams.height = WindowManager.LayoutParams.WRAP_CONTENT;
  49. // 设置窗体显示的位置,否则在屏幕中心显示
  50. mLayoutParams.x = 50;
  51. mLayoutParams.y = 50;
  52. }
  53. private void onActionMove(MotionEvent event) {
  54. if (event.getAction() == MotionEvent.ACTION_DOWN) {
  55. long end = System.currentTimeMillis() - starttime;
  56. // 双击的间隔在 200ms 到 500ms 之间
  57. if (end > 200 && end < 500) {
  58. closeDesk();
  59. return;
  60. }
  61. starttime = System.currentTimeMillis();
  62. }
  63. mLayoutParams.x = (int) (event.getRawX() - (mDesktopLayout.getWidth()));
  64. mLayoutParams.y = (int) (event.getRawY() - (mDesktopLayout.getHeight()));
  65. mWindowManager.updateViewLayout(mDesktopLayout, mLayoutParams);
  66. }
  67. /**
  68. * 显示DesktopLayout
  69. */
  70. private void showDesk() {
  71. mWindowManager.addView(mDesktopLayout, mLayoutParams);
  72. finish();
  73. }
  74. /**
  75. * 关闭DesktopLayout
  76. */
  77. private void closeDesk() {
  78. mWindowManager.removeView(mDesktopLayout);
  79. finish();
  80. }
  81. public void onCreate(Bundle savedInstanceState) {
  82. super.onCreate(savedInstanceState);
  83. setContentView(R.layout.main);
  84. createWindowManager();
  85. createDesktopLayout();
  86. Button btn = (Button) findViewById(R.id.btn);
  87. btn.setOnClickListener(new OnClickListener() {
  88. public void onClick(View v) {
  89. showDesk();
  90. }
  91. });
  92. }
  93. }

显示的效果:

悬浮窗体例子

http://blog.csdn.net/xyz_fly/article/details/7546096

android编程之悬浮窗体的更多相关文章

  1. 【Android Demo】悬浮窗体实现

    突然对悬浮窗体感兴趣,查资料做了个小Demo,效果是点击按钮后,关闭当前Activity,显示悬浮窗口,窗口可以拖动,双击后消失.效果图如下: 它的使用原理很简单,就是借用了WindowManager ...

  2. Android仿360悬浮小球自定义view实现

    转载请标明出处:http://www.jianshu.com/u/a5ad093cffe8 效果图如下: 图片.png   图片.png 实现当前这种类似的效果 (360小球 悬浮桌面差不错类似).第 ...

  3. 读《Android编程权威指南》

    因为去年双十二购买了一折的<Android 编程权威指南(第一版)>,在第二版出来后图灵社区给我推送了第二版的优惠码,激动之余就立马下单购买电子书,不得不说Big Nerd Ranch G ...

  4. 菜鸟学Android编程——简单计算器《一》

    菜鸟瞎搞,高手莫进 本人菜鸟一枚,最近在学Android编程,网上看了一些视频教程,于是想着平时手机上的计算器应该很简单,自己何不尝试着做一个呢? 于是就冒冒失失的开撸了. 简单计算器嘛,功能当然很少 ...

  5. [电子书] 《Android编程入门很简单》

    <Android编程入门很简单>是一本与众不同的Android学习读物,是一本化繁为简,把抽象问题具体化,把复杂问题简单化的书.本书避免出现云山雾罩.晦涩难懂的讲解,代之以轻松活泼.由浅入 ...

  6. 从零开始学android开发- 应用程序窗体显示状态操作requestWindowFeature

    我们在开发程序是经常会需要软件全屏显示.自定义标题(使用按钮等控件)和其他的需求,今天这一讲就是如何控制Android应用程序的窗体显示. 首先介绍一个重要方法那就是requestWindowFeat ...

  7. Eclipse下Android编程代码自动提示

    在用Eclipse进行Android编程,为了代码自动提示,需要进行如下操作: 1.设置 java 文件的代码提示功能 打 开 Eclipse 依次选择 Window > Preferences ...

  8. Matlab.NET混合编程调用Figure窗体

    原文:[原创]Matlab.NET混合编程调用Figure窗体 1.前言 做Matlab.NET混合编程好几年了,虽然Matlab很多函数忘记得差不多了,但基本的东西还是能熟练使用.特别是在C#调用M ...

  9. Android编程心得-在任意类中获取当前屏幕宽高

    进行Android编程时,很多时候都需要获取当前屏幕的宽度与高度,但是当我们需要在别的类中调用屏幕宽高时,直接用原来的方法是不行的,下面我来介绍如何在任意类中调用宽度高度的两种方法. public v ...

随机推荐

  1. CSS padding margin border属性详解【转载】

    本文转载自:http://www.cnblogs.com/linjiqin/p/3556497.html ,感谢相关博主. 图解CSS padding.margin.border属性 W3C组织建议把 ...

  2. Oracle执行计划——使用index full scan的几种情况

    常见有三种情况都有用到indexfull scan. 1. 查询列就是索引列 2. 对索引列进行order by时 3. 对索列进行聚合计算时

  3. BootStrap--Tables(表格) MVC中不刷新做增,删,改(C#)

    自带的Tables会有自动分页,搜索等一些动能,很方便,唯一的不足就是添加,修改,删除数据需要刷新页面,并不能静态. 下面说的是如何不刷新页面(Ajax)去执行增,删,改操作. 需要用到的样式,JS库 ...

  4. nagios 实现Mysql 主从同步状态的监控

    一.系统环境 主机名 IP nagios 192.168.15.111 mysql_s 192.168.15.21 二.操作步骤 2.1 mysql_s端的配置 2.1.1 编写check_mysql ...

  5. url参数中有+、空格、=、%、&、#等特殊符号的处理

    url参数中有+.空格.=.%.&.#等特殊符号的问题解决? 解决办法: 将这些字符转化成服务器可以识别的字符,对应关系如下: URL字符转义 + URL 中+号表示空格 %2B 空格 URL ...

  6. git查看某个文件的修改历史

    <转自 http://www.cnblogs.com/flyme/archive/2011/11/28/2265899.html> 有时候在比对代码时,看到某些改动,但不清楚这个改动的作者 ...

  7. TreeView绑定无限层级关系类

    protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) { Bind_TV(TreeView1.Nodes); ...

  8. Android学习手记(5) 基本UI布局

    1.View和ViewGroup Activity是Android应用程序的基本管理单元,Android的每一个窗口都是通过一个Activity来定义的,但是Activity并不能直接用来显示窗口.我 ...

  9. mysql存储过程controller的not found造成混乱的解决办法

    打草稿 问题:对于select  var1 into var2 ,单select的结果为空的时候(空的意思是没有找到数据,不是该值为null) ,会触发controller的not found 当游标 ...

  10. oracle 数据库开发面试题,当时笔试的时候一个没做出来,现附原题及答案

    1. ID123567810111215 表名tt,用sql找出ID列中不连续的ID,例如其中没有的4: --创建表及数据 CREATE TABLE tt(ID INTEGER); INSERT IN ...