【Android Demo】悬浮窗体实现
突然对悬浮窗体感兴趣,查资料做了个小Demo,效果是点击按钮后,关闭当前Activity,显示悬浮窗口,窗口可以拖动,双击后消失。效果图如下:

它的使用原理很简单,就是借用了WindowManager这个管理类来实现的。
1.首先在AndroidManifest.xml中添加使用权限:
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
2.悬浮窗口布局实现
public class DesktopLayout extends LinearLayout {
public DesktopLayout(Context context) {
super(context);
setOrientation(LinearLayout.VERTICAL);// 水平排列
//设置宽高
this.setLayoutParams( new LayoutParams(LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT));
View view = LayoutInflater.from(context).inflate(
R.layout.desklayout, null);
this.addView(view);
}
3.在activity中让它显示出来。
// 取得系统窗体
mWindowManager = (WindowManager) getApplicationContext()
.getSystemService("window"); // 窗体的布局样式
mLayout = new WindowManager.LayoutParams(); // 设置窗体显示类型——TYPE_SYSTEM_ALERT(系统提示)
mLayout.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT; // 设置窗体焦点及触摸:
// FLAG_NOT_FOCUSABLE(不能获得按键输入焦点)
mLayout.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; // 设置显示的模式
mLayout.format = PixelFormat.RGBA_8888; // 设置对齐的方法
mLayout.gravity = Gravity.TOP | Gravity.LEFT; // 设置窗体宽度和高度
mLayout.width = WindowManager.LayoutParams.WRAP_CONTENT;
mLayout.height = WindowManager.LayoutParams.WRAP_CONTENT;
详细 MainActivity 代码如下:
package com.yc.yc_suspendingform; import android.app.Activity;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.os.Bundle;
import android.util.Log;
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;
import com.yc.yc_floatingform.R; public class MainActivity extends Activity {
private WindowManager mWindowManager;
private WindowManager.LayoutParams mLayout;
private DesktopLayout mDesktopLayout;
private long startTime;
// 声明屏幕的宽高
float x, y;
int top; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
createWindowManager();
createDesktopLayout();
Button btn = (Button) findViewById(R.id.btn);
btn.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
showDesk();
}
});
}
/**
* 创建悬浮窗体
*/
private void createDesktopLayout() {
mDesktopLayout = new DesktopLayout(this);
mDesktopLayout.setOnTouchListener(new OnTouchListener() {
float mTouchStartX;
float mTouchStartY; @Override
public boolean onTouch(View v, MotionEvent event) {
// 获取相对屏幕的坐标,即以屏幕左上角为原点
x = event.getRawX();
y = event.getRawY() - top; // 25是系统状态栏的高度
Log.i("startP", "startX" + mTouchStartX + "====startY"
+ mTouchStartY);
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
// 获取相对View的坐标,即以此View左上角为原点
mTouchStartX = event.getX();
mTouchStartY = event.getY();
Log.i("startP", "startX" + mTouchStartX + "====startY"
+ mTouchStartY);
long end = System.currentTimeMillis() - startTime;
// 双击的间隔在 300ms以下
if (end < 300) {
closeDesk();
}
startTime = System.currentTimeMillis();
break;
case MotionEvent.ACTION_MOVE:
// 更新浮动窗口位置参数
mLayout.x = (int) (x - mTouchStartX);
mLayout.y = (int) (y - mTouchStartY);
mWindowManager.updateViewLayout(v, mLayout);
break;
case MotionEvent.ACTION_UP: // 更新浮动窗口位置参数
mLayout.x = (int) (x - mTouchStartX);
mLayout.y = (int) (y - mTouchStartY);
mWindowManager.updateViewLayout(v, mLayout); // 可以在此记录最后一次的位置 mTouchStartX = mTouchStartY = 0;
break;
}
return true;
}
});
} @Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
Rect rect = new Rect();
// /取得整个视图部分,注意,如果你要设置标题样式,这个必须出现在标题样式之后,否则会出错
getWindow().getDecorView().getWindowVisibleDisplayFrame(rect);
top = rect.top;//状态栏的高度,所以rect.height,rect.width分别是系统的高度的宽度 Log.i("top",""+top);
} /**
* 显示DesktopLayout
*/
private void showDesk() {
mWindowManager.addView(mDesktopLayout, mLayout);
finish();
} /**
* 关闭DesktopLayout
*/
private void closeDesk() {
mWindowManager.removeView(mDesktopLayout);
finish();
} /**
* 设置WindowManager
*/
private void createWindowManager() {
// 取得系统窗体
mWindowManager = (WindowManager) getApplicationContext()
.getSystemService("window"); // 窗体的布局样式
mLayout = new WindowManager.LayoutParams(); // 设置窗体显示类型——TYPE_SYSTEM_ALERT(系统提示)
mLayout.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT; // 设置窗体焦点及触摸:
// FLAG_NOT_FOCUSABLE(不能获得按键输入焦点)
mLayout.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; // 设置显示的模式
mLayout.format = PixelFormat.RGBA_8888; // 设置对齐的方法
mLayout.gravity = Gravity.TOP | Gravity.LEFT; // 设置窗体宽度和高度
mLayout.width = WindowManager.LayoutParams.WRAP_CONTENT;
mLayout.height = WindowManager.LayoutParams.WRAP_CONTENT; } }
源代码地址:https://github.com/YeXiaoChao/Yc_suspendingform
本文地址:www.cnblogs.com/yc-755909659/p/4281214.html
PS:本文由J灬叶小超原创,如有转载请注明出处,谢谢!
【Android Demo】悬浮窗体实现的更多相关文章
- android编程之悬浮窗体
用过手机360和QQ手机管家等一些软件的朋友,会发现,在这些应用中,会出现一个悬浮窗体,例如QQ手机管家中打电话的场景: 这种窗体除了会显示外,还可以移动它的位置,并且一直显示.除了关闭当前程序外,窗 ...
- Android WindowManager悬浮窗:不需要申请权限实现悬浮
Android WindowManager悬浮窗:不需要申请权限实现悬浮 附录文章1介绍了Android平台上的悬浮窗WindowManager,WindowManager悬浮窗可以悬浮在And ...
- Android EditText悬浮在输入法之上
Android EditText悬浮在输入法之上 使用 android:windowSoftInputMode="adjustResize" 会让界面整体被顶上去,很多时候我们不需 ...
- Android -- 桌面悬浮,QQ管家火箭实现
续上一篇博客<Android -- 桌面悬浮,仿360>,传送门:http://www.cnblogs.com/yydcdut/p/3909888.html,在此代码上继续添加实现. 比起 ...
- LeadTools Android 入门教学——运行第一个Android Demo
LeadTools 有很多Windows平台下的Demo,非常全面,但是目前开发手机应用的趋势也越来越明显,LeadTools也给大家提供了10个Android的Demo,这篇文章将会教你如何运行第一 ...
- 【Android】如何快速构建Android Demo
[Android]如何快速构建Android Demo 简介 在 Android 学习的过程中,经常需要针对某些项目来写一些测试的例子,或者在做一些 demo 的时候,都需要先写 Activity 然 ...
- Android 之 悬浮窗
昨天研究Android的悬浮窗,遇到一个问题,研究了一天,总算找到结症了,原因非常坑人..... 问题是这样的,我想要将悬浮窗展现在桌面或其他应用之上,我的开发机子用的是MIUI,结果发现在机子上无论 ...
- 制作Android Demo GIF:程序演示效果GIF图录制
[转] 制作Android Demo GIF:程序演示效果GIF图录制 在平时写博客或者分享自己写的程序效果的时候经常需要做成GIF图,以下就是介绍几种常用的GIF录制方法: 一.录制工具 1.( ...
- Ubuntu TensorFlow 源码 Android Demo的编译运行
Ubuntu TensorFlow 源码 Android Demo的编译运行 一. 安装 Android 的SDK和NDK SDK 配置 A:下载 国内下载地址选最新的: SDK: https://d ...
随机推荐
- 35 Gallery – Ajax Slide
http://html5up.net/overflow (PC,Mobile,Table) http://bridge.net/ https://github.com/bridgedotnet/Bri ...
- MyBatis中的特殊符号[20160713]
今天中午回到工位已经是12:20多了,没有时间睡觉了,本想着还能提前开始,结果看了点新闻之后,又是12:40了,所以新闻坚决不能看,执行力. 今天主要记录一下MyBatis中的特殊符号的问题,这个问题 ...
- C#中的接口实现多态
我们都知道虚方法实现多态,抽象方法实现多态等,我们今天来看看如何使用接口实现多态 1.首先我们先要来了解了解什么是接口,它存在的意识 01.接口就是为了约束方法的格式(参数和返回值类型)而存在的 02 ...
- QT分页控件,开源,供大家使用
下载地址:http://files.cnblogs.com/dragonsuc/qt5.rar
- C#获取网上图片的宽高代码
用Visual Studio建立Console应用程序,记得引用程序集System.Drawing; 代码如下: using System;using System.Drawing;using Sys ...
- XStream的例子
写个小例子,方便以后复习: 1 package com.demo; 2 3 import java.util.ArrayList; 4 import java.util.List; 5 6 impor ...
- 2015年第3本(英文第2本):Daughter of Deceit
书名:Daughter of Deceit 作者: Victoria Holt (维多丽亚·荷特) 单词数:12万 词汇量:6000 首万词不重复词数:1700 蓝思值:570 阅读时间:1月12日- ...
- Sharepoint学习笔记—习题系列--70-573习题解析 -(Q25-Q27)
Question25You develop a new publishing page layout named MyPage.aspx for a SharePoint site.You creat ...
- Objective-C之用C的字符来处理NSString相关的字符替换和拼接的问题
*:first-child { margin-top: 0 !important; } body > *:last-child { margin-bottom: 0 !important; } ...
- 小波说雨燕 第三季 构建 swift UI 之 UI组件集-视图集(一)视图共性 学习笔记
如果想进行自定义的配置,可以继承基类UIView. 地图app中需要多点触动Multiple Touch, opaque不透明的 hidden隐藏的 比如下载的进度条,如果下载完毕,可以通过设置这个属 ...