一、前言:

我手机从来不装这些东西,不过,有次看到同事的android手机上,有个QQ管家在桌面上浮着,同事拖动管家时,管家就变成一只鸟,桌面下方还有个弹弓,桌面顶部有只乌鸦,把管家也就是鸟拖动到弹弓那,然后,松手,鸟就飞出去。这个过程是动画过程,做的事,实际上是清楚内存。

二:原理:

其实,没什么原理,用到的就是WindowManager以及WindowManager.LayoutParams,对这个LayoutParams做文章,当设置为属性后,然后,创建一个View,将这个View添加到WindowManager中就行。

package com.chris.floats.window;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.view.Gravity;
import android.view.WindowManager;
import android.app.Activity;
import android.content.Context;
public class MainActivity extends Activity {
private static WindowManager mWindowMgr = null;
private WindowManager.LayoutParams mWindowMgrParams = null;
private static FloatsWindowView mFloatsWindowView = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
/*
* 显示应用主界面时,去除悬浮层
*/
@Override
public void onWindowFocusChanged(boolean hasFocus) {
if(hasFocus){
if(mFloatsWindowView != null){
mWindowMgr.removeView(mFloatsWindowView);
mFloatsWindowView = null;
}
}else{
getWindowLayout();
}
}
private void initParams(){
DisplayMetrics dm = getResources().getDisplayMetrics();
mWindowMgrParams.x = dm.widthPixels - 136;
mWindowMgrParams.y = 300;
mWindowMgrParams.width = 136;
mWindowMgrParams.height = 136;
}
private void getWindowLayout(){
if(mFloatsWindowView == null){
mWindowMgr = (WindowManager)getBaseContext().getSystemService(Context.WINDOW_SERVICE);
mWindowMgrParams = new WindowManager.LayoutParams();
/*
*  2003 在指悬浮在所有界面之上
*  (4.0+系统中,在下拉菜单下面,而在2.3中,在上拉菜单之上)
*/
mWindowMgrParams.type = 2003;
mWindowMgrParams.format = 1;
/*
* 代码实际是wmParams.flags |= FLAG_NOT_FOCUSABLE;
* 40的由来是wmParams的默认属性(32)+ FLAG_NOT_FOCUSABLE(8)
*/
mWindowMgrParams.flags = 40;
mWindowMgrParams.gravity = Gravity.LEFT | Gravity.TOP;
initParams();
mFloatsWindowView = new FloatsWindowView(this);
mWindowMgr.addView(mFloatsWindowView, mWindowMgrParams);
}
}
}

上面代码,主要在getWindowLayout函数中,最后两行就是创建一个View,并加入到WindowManager中。

继承View的悬浮View:

package com.chris.floats.window;
import android.content.Context;
import android.content.Intent;
import android.graphics.drawable.AnimationDrawable;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewTreeObserver.OnPreDrawListener;
import android.view.WindowManager;
public class FloatsWindowView extends View {
private Context mContext = null;
private WindowManager mWindowMgr = null;
private WindowManager.LayoutParams mWindowMgrParams = null;
private AnimationDrawable mAnimationDrawable = null;
private int iPosX = 0;
private int iPosY = 0;
private int iLastPosX = 0;
private int iLastPosY = 0;
private boolean bMoved = false;
public FloatsWindowView(Context context) {
this(context, null, 0);
}
public FloatsWindowView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public FloatsWindowView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
mContext = context;
mWindowMgr = (WindowManager)getContext().getApplicationContext().getSystemService("window");
mWindowMgrParams = new WindowManager.LayoutParams();
initParams();
mAnimationDrawable = new AnimationDrawable();
for(int i = 0; i < 4; i++){
int id = getResources().getIdentifier("a"+ i, "drawable", mContext.getPackageName());
mAnimationDrawable.addFrame(getResources().getDrawable(id), 100);
}
mAnimationDrawable.setOneShot(false);
this.setBackgroundDrawable(mAnimationDrawable);
OnPreDrawListener listener = new OnPreDrawListener(){
@Override
public boolean onPreDraw() {
mAnimationDrawable.start();
return true;
}
};
this.getViewTreeObserver().addOnPreDrawListener(listener);
}
private void initParams(){
DisplayMetrics dm = getResources().getDisplayMetrics();
mWindowMgrParams.x = dm.widthPixels - 136;
mWindowMgrParams.y = 300;
mWindowMgrParams.width = 136;
mWindowMgrParams.height = 136;
}
@Override
public boolean onTouchEvent(MotionEvent event) {
switch(event.getAction()){
case MotionEvent.ACTION_DOWN:
iPosX = (int)event.getX();
iPosY = (int)event.getY();
bMoved = false;
break;
case MotionEvent.ACTION_MOVE:
bMoved = true;
iLastPosX = (int)event.getX();
iLastPosY = (int)event.getY();
updatePostion(iLastPosX - iPosX, iLastPosY - iPosY);
break;
case MotionEvent.ACTION_UP:
if(!bMoved){
Intent it=new Intent(mContext, MainActivity.class);
mContext.startActivity(it);
}
break;
default:
break;
}
return true;
}
private void updatePostion(int x, int y){
mWindowMgrParams.type = 2003;
mWindowMgrParams.format = 1;
mWindowMgrParams.flags = 40;
mWindowMgrParams.gravity = Gravity.LEFT | Gravity.TOP;
mWindowMgrParams.x += x;
mWindowMgrParams.y += y;
mWindowMgr.updateViewLayout(this, mWindowMgrParams);
}
}

之所以将updatePosition中的参数与Activity中设置一样,是为了确保在MOVE时,造成相对位置的不一样,而导致闪砾,大家要是不理解,可以实验下。

三、小结:

这篇文章实现了简单的悬浮窗口动画效果,如果要想做成像360,QQ管家那样,还需要一些其它的操作:

1. 比如启动一个后台服务来监控系统信息;

2. ACTION_DOWN时,修改悬浮窗口上的图片;

3. ACTION_MOVE时窗口跟随;

4. ACTION_UP时,创建一个线程,来完成释放后,向上运动的动画过程等;

本篇源码包,会将在下篇文章《Android应用图标在状态栏上显示,以及显示不同的图标》一起给出。

Android类似360,QQ管家那样的悬浮窗相关推荐

  1. Android类似360,QQ管家那样的悬浮窗 for android3

        发表于 2013-6-24 20:26:57  | 只看该作者 一.前言: 我手机从来不装这些东西,不过,有次看到同事的android手机上,有个QQ管家在桌面上浮着,同事拖动管家时,管家就变 ...

  2. android 360 悬浮窗口,Android实现类似360,QQ管家那样的悬浮窗

    一.前言: 我手机从来不装这些东西,不过,有次看到同事的android手机上,有个QQ管家在桌面上浮着,同事拖动管家时,管家就变成一只鸟,桌面下方还有个弹弓,桌面顶部有只乌鸦,把管家也就是鸟拖动到弹弓 ...

  3. Android实现类似360,QQ管家那样的悬浮窗

    一.前言:  我手机从来不装这些东西,不过,有次看到同事的android手机上,有个QQ管家在桌面上浮着,同事拖动管家时,管家就变成一只鸟,桌面下方还有个弹弓,桌面顶部有只乌鸦,把管家也就是鸟拖动到弹 ...

  4. android 仿qq好友动态,Android UI仿QQ好友列表分组悬浮效果

    本文实例为大家分享了Android UI仿QQ好友列表分组悬浮效果的具体代码,供大家参考,具体内容如下 楼主是在平板上測试的.图片略微有点大,大家看看效果就好 接下来贴源代码: PinnedHeade ...

  5. android中检测网速,Android 流量与网速监测(悬浮窗) 源码

    [实例简介] 对应博文链接:http://blog.csdn.net/yyh352091626/article/details/50599621 Android 实现流量与网速监测(悬浮窗) 源码. ...

  6. Android聊天室源码开发,悬浮窗的实现及封装思路

    为了实现语音聊天室源码的多场景应用,悬浮小窗口在语音聊天室源码开发中还是比较常见的需求,主要是指用户在语音连麦过程中打开其它界面或者退到桌面时语音连麦不会中断且会有一个悬浮小窗口位于最上层,接下来我们 ...

  7. Android仿腾讯手机管家实现桌面悬浮窗小火箭发射的动画效果

    功能分析:  1.小火箭游离在activity之外,不依附于任何activity,不管activity是否开启,不影响小火箭的代码逻辑,所以小火箭的代码逻辑是要写在服务中:  2.小火箭挂载在手机窗体 ...

  8. Android 自定义水波球清理内存的悬浮窗小工具

    一.概述 现在一些手机管家都会有一个用来清理内存的悬浮窗小工具,感觉挺实用的,就自己做了一个.首先介绍一下这个工具的功能,除了可以清理内存,还有调节手机屏幕亮度.手电筒.无线网.移动数据.蓝牙.GPS ...

  9. android动态申请悬浮框权限,Android动态权限申请工具(包括悬浮窗)

    为了保证APP正常运行,动态权限申请是android比较常用的功能,由于每次都需要做申请.等待返回还有拒绝反馈等操作,比较麻烦,所以集成了一个比较简单的动态权限申请库 集成方法: Step 1. Ad ...

最新文章

  1. 在.NET 3.5 平台上使用LINQ to SQL创建三层/多层Web应用系统(Part5) 转
  2. Spring注解大全(示例详解)
  3. 【MM】新建移动类型(Movement Type)
  4. 【彩彩只能变身队】后端工作总结
  5. 分布式事务 camel_使用Camel在Amazon上构建分布式工作流应用程序
  6. 深度学习中的内存管理问题研究综述
  7. 服务器自动post,Go Web服务器自动重定向POST请求
  8. PVID、Access、Trunk、Hybrid三种不同端口收发规则、Vlan中tagged端口和untagged端口的区别
  9. 用极域课堂管理系统软件批量格式化D盘
  10. java导出建表语句_由 Java Entity 类自动生成 SQL建表语句
  11. 高效 Windows 工作环境 Java 开发环境搭建
  12. 如何选购计算机硬盘,如何挑选固态硬盘,教您电脑固态硬盘如何挑选
  13. PHP从入门到接到外包合同,再到放弃
  14. 服务器背板电源维修,814835-B21 814832-001 DD-2901-3C-LF G9 HPE服务器电源背板
  15. 零伽壹产业研究:新商业奇观元宇宙,多种技术的集大成者
  16. 工业软件CAD、CAE、CAM介绍
  17. 应用安装失败“The application could not be installed: INSTALL_FAILED_USER_RESTRICTED”问题解决
  18. spring cloud contract的应用实现与概念理解-服务提供者一侧的落地
  19. 【Linux】ARM篇七--WDT看门狗实验
  20. centos7 Kubeadm安装配置K8S 及Dashboard外部服务

热门文章

  1. Mask R-CNN详解(图文并茂)
  2. 酸酸甜甜的杨梅数据库
  3. mysql的union和union all
  4. Hadoop Kerberos 集成
  5. Python 低功耗蓝牙搜索与连接
  6. Quartz使用问题记录
  7. ios 线条球_iOS 圆球加载动画解析
  8. Simple Siamese
  9. 学计算机基础知识的软件,你是不是很难学会电脑应用软件,请先学习计算机科学的基础知识...
  10. MASK RCNN 之RPN