android编程之悬浮窗体
用过手机360和QQ手机管家等一些软件的朋友,会发现,在这些应用中,会出现一个悬浮窗体,例如QQ手机管家中打电话的场景:
这种窗体除了会显示外,还可以移动它的位置,并且一直显示。除了关闭当前程序外,窗口不会主动消失。其实,它的使用原理也很简单,就是借用了WindowManager这个管理类来实现的。
注意:要在AndroidManifest.xml中添加使用权限:
- <uses-permission
- android:name="android.permission.SYSTEM_ALERT_WINDOW" />
这里,我采用代码布局的方式,模仿了一下QQ这个界面效果:
- import android.content.Context;
- import android.widget.ImageView;
- import android.widget.LinearLayout;
- import android.widget.TextView;
- public class DesktopLayout extends LinearLayout {
- public DesktopLayout(Context context) {
- super(context);
- setOrientation(LinearLayout.HORIZONTAL);
- LayoutParams mLayoutParams = new LayoutParams(
- LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
- setLayoutParams(mLayoutParams);
- // 显示的ICON
- ImageView mImageView = new ImageView(context);
- mImageView.setImageResource(R.drawable.icon);
- addView(mImageView, mLayoutParams);
- // 显示的文字
- TextView mTextView = new TextView(context);
- mTextView.setText("Hello");
- mTextView.setTextSize(30);
- addView(mTextView, mLayoutParams);
- }
- }
接下来,在activity中让它显示出来。首先要设置一下WindowManager.LayoutParams:
- // 取得系统窗体
- mWindowManager = (WindowManager) getApplicationContext()
- .getSystemService("window");
- // 窗体的布局样式
- mLayoutParams = new WindowManager.LayoutParams();
- // 设置窗体显示类型——TYPE_SYSTEM_ALERT(系统提示)
- mLayoutParams.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;
- // 设置窗体焦点及触摸:
- // FLAG_NOT_FOCUSABLE(不能获得按键输入焦点)
- mLayoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
- // 设置显示的模式
- mLayoutParams.format = PixelFormat.RGBA_8888;
- // 设置对齐的方法
- mLayoutParams.gravity = Gravity.TOP | Gravity.LEFT;
- // 设置窗体宽度和高度
- mLayoutParams.width = WindowManager.LayoutParams.WRAP_CONTENT;
- mLayoutParams.height = WindowManager.LayoutParams.WRAP_CONTENT;
- // 设置窗体显示的位置,否则在屏幕中心显示
- mLayoutParams.x = 50;
- mLayoutParams.y = 50;
显示窗体与关闭窗体的方法:
- mWindowManager.addView(mDesktopLayout, mLayoutParams);
- mWindowManager.removeView(mDesktopLayout);
以下是activity的原代码,这里设计了一个双击关闭窗体的效果:
- import android.app.Activity;
- import android.graphics.PixelFormat;
- import android.os.Bundle;
- import android.view.Gravity;
- import android.view.MotionEvent;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.view.View.OnTouchListener;
- import android.view.WindowManager;
- import android.widget.Button;
- public class DeskTip extends Activity {
- private WindowManager mWindowManager;
- private WindowManager.LayoutParams mLayoutParams;
- private DesktopLayout mDesktopLayout;
- private long starttime;
- /**
- * 创建悬浮窗体
- */
- private void createDesktopLayout() {
- mDesktopLayout = new DesktopLayout(this);
- mDesktopLayout.setOnTouchListener(new OnTouchListener() {
- public boolean onTouch(View v, MotionEvent event) {
- onActionMove(event);
- return true;
- }
- });
- }
- /**
- * 设置WindowManager
- */
- private void createWindowManager() {
- // 取得系统窗体
- mWindowManager = (WindowManager) getApplicationContext()
- .getSystemService("window");
- // 窗体的布局样式
- mLayoutParams = new WindowManager.LayoutParams();
- // 设置窗体显示类型——TYPE_SYSTEM_ALERT(系统提示)
- mLayoutParams.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;
- // 设置窗体焦点及触摸:
- // FLAG_NOT_FOCUSABLE(不能获得按键输入焦点)
- mLayoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
- // 设置显示的模式
- mLayoutParams.format = PixelFormat.RGBA_8888;
- // 设置对齐的方法
- mLayoutParams.gravity = Gravity.TOP | Gravity.LEFT;
- // 设置窗体宽度和高度
- mLayoutParams.width = WindowManager.LayoutParams.WRAP_CONTENT;
- mLayoutParams.height = WindowManager.LayoutParams.WRAP_CONTENT;
- // 设置窗体显示的位置,否则在屏幕中心显示
- mLayoutParams.x = 50;
- mLayoutParams.y = 50;
- }
- private void onActionMove(MotionEvent event) {
- if (event.getAction() == MotionEvent.ACTION_DOWN) {
- long end = System.currentTimeMillis() - starttime;
- // 双击的间隔在 200ms 到 500ms 之间
- if (end > 200 && end < 500) {
- closeDesk();
- return;
- }
- starttime = System.currentTimeMillis();
- }
- mLayoutParams.x = (int) (event.getRawX() - (mDesktopLayout.getWidth()));
- mLayoutParams.y = (int) (event.getRawY() - (mDesktopLayout.getHeight()));
- mWindowManager.updateViewLayout(mDesktopLayout, mLayoutParams);
- }
- /**
- * 显示DesktopLayout
- */
- private void showDesk() {
- mWindowManager.addView(mDesktopLayout, mLayoutParams);
- finish();
- }
- /**
- * 关闭DesktopLayout
- */
- private void closeDesk() {
- mWindowManager.removeView(mDesktopLayout);
- finish();
- }
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- createWindowManager();
- createDesktopLayout();
- Button btn = (Button) findViewById(R.id.btn);
- btn.setOnClickListener(new OnClickListener() {
- public void onClick(View v) {
- showDesk();
- }
- });
- }
- }
显示的效果:
http://blog.csdn.net/xyz_fly/article/details/7546096
android编程之悬浮窗体的更多相关文章
- 【Android Demo】悬浮窗体实现
突然对悬浮窗体感兴趣,查资料做了个小Demo,效果是点击按钮后,关闭当前Activity,显示悬浮窗口,窗口可以拖动,双击后消失.效果图如下: 它的使用原理很简单,就是借用了WindowManager ...
- Android仿360悬浮小球自定义view实现
转载请标明出处:http://www.jianshu.com/u/a5ad093cffe8 效果图如下: 图片.png 图片.png 实现当前这种类似的效果 (360小球 悬浮桌面差不错类似).第 ...
- 读《Android编程权威指南》
因为去年双十二购买了一折的<Android 编程权威指南(第一版)>,在第二版出来后图灵社区给我推送了第二版的优惠码,激动之余就立马下单购买电子书,不得不说Big Nerd Ranch G ...
- 菜鸟学Android编程——简单计算器《一》
菜鸟瞎搞,高手莫进 本人菜鸟一枚,最近在学Android编程,网上看了一些视频教程,于是想着平时手机上的计算器应该很简单,自己何不尝试着做一个呢? 于是就冒冒失失的开撸了. 简单计算器嘛,功能当然很少 ...
- [电子书] 《Android编程入门很简单》
<Android编程入门很简单>是一本与众不同的Android学习读物,是一本化繁为简,把抽象问题具体化,把复杂问题简单化的书.本书避免出现云山雾罩.晦涩难懂的讲解,代之以轻松活泼.由浅入 ...
- 从零开始学android开发- 应用程序窗体显示状态操作requestWindowFeature
我们在开发程序是经常会需要软件全屏显示.自定义标题(使用按钮等控件)和其他的需求,今天这一讲就是如何控制Android应用程序的窗体显示. 首先介绍一个重要方法那就是requestWindowFeat ...
- Eclipse下Android编程代码自动提示
在用Eclipse进行Android编程,为了代码自动提示,需要进行如下操作: 1.设置 java 文件的代码提示功能 打 开 Eclipse 依次选择 Window > Preferences ...
- Matlab.NET混合编程调用Figure窗体
原文:[原创]Matlab.NET混合编程调用Figure窗体 1.前言 做Matlab.NET混合编程好几年了,虽然Matlab很多函数忘记得差不多了,但基本的东西还是能熟练使用.特别是在C#调用M ...
- Android编程心得-在任意类中获取当前屏幕宽高
进行Android编程时,很多时候都需要获取当前屏幕的宽度与高度,但是当我们需要在别的类中调用屏幕宽高时,直接用原来的方法是不行的,下面我来介绍如何在任意类中调用宽度高度的两种方法. public v ...
随机推荐
- Selenium IDE整理
安装 Step1: 下载Firefox浏览器 http://www.firefox.com.cn/ Step2: 安装Selenium IDE插件 http://seleniumhq.org/down ...
- Selenium webdriver 封装与重用
WebDriver对页面的操作,需要找到一个WebElement,然后再对其进行操作,比较繁琐: WebElement element =driver.findElement(By.name(&quo ...
- C#日历上显示节气、阴阳历节假日信息
近期在做一个工作日历,想在日历上设置工作日,显示请假.加班等相关信息,显示农历日期信息(包括农历日期.节日 .节气).公历信息(节假期). 不能不说,http://www.cnblogs.com/ho ...
- 手机端H5点击类目自动定位到相应内容
_obj = {}; /*点击弹出分类*/_obj.openZZ=function(){ document.getElementById("app_screen01").style ...
- File类学习笔记
File类 首先,要明确的一点就是,在整个IO包中,唯一表示与文件有关的类局势File类. 它可以实现创建或删除文件等操作.下面看看它的构造方法: File(String pathname) 通过将给 ...
- Event Delivery: The Responder Chain(事件传递,响应链)
当我们设计app的时候,我们很可能想动态的响应事件.例如,触摸一个拥有许多不同对象的屏幕,你要决定给哪个对象一个响应事件,怎么样对象接收到事件. 当一个用户产生事件发生时(如 点击),UIKit产生一 ...
- ajax与Servlet
1.后台返回text类型的数据 <%@ page language="java" import="java.util.*" pageEncoding=&q ...
- 深入理解 CSS变形 transform(3d)
坐标轴 在了解透视之前,首先要先了解坐标轴.3D变形与2D变形最大的不同就在于其参考的坐标轴不同.2D变形的坐标轴是平面的,只存在x轴和y轴,而3D变形的坐标轴则是x.y.z三条轴组成的立体空间,x轴 ...
- 3.RxJava详解
一.RxJava 到底是什么 异步(取代AsyncTask/Handler/XXX/...?) 二.RxJava 好在哪 简洁(逻辑的简洁,.一步一走) 举例: 题目:将文件夹中的图片都取 ...
- Andoid源码 BUG修改集合--不断更新
BUG001:很抱歉,***已停止运行 网上查找问题原因很多,有人说事缓存不够,作为一个开发者,需要从代码解决问题 比如,这次遇到一个"很抱歉,instant已停止运行",inst ...