创建一个Window是很简单的事,只需要通过WindowManager即可完成。WindowManager是外界访问Window的入口。使用WindowManager可以在其他应用最上层,甚至手机桌面最上层显示窗口。通过(WindowManager)getApplicationContext().getSystemService(Context.WINDOW_SERVICE); 即可获得WindowManager对象,调用的是WindowManager继承自基类的addView方法和removeView方法来显示和隐藏窗口。

下面是Android Window悬浮窗的一个小例子,类似于360手机桌面加速球,该加速球可以在桌面拖动,点击后开始转动(此时可以进行如清理垃圾的操作)。

package com.hongri.recyclerview.activity;import android.animation.Animator;
import android.animation.AnimatorInflater;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.provider.Settings;
import android.view.Gravity;
import android.view.WindowManager;
import android.widget.ImageView;
import android.widget.Toast;import com.hongri.recyclerview.MyApplication;
import com.hongri.recyclerview.R;
import com.hongri.recyclerview.fragment.HomeFragment;
import com.hongri.recyclerview.utils.Logger;
import com.hongri.recyclerview.widget.FloatView;/*** @author:zhongyao * @description:主界面Activity*/
public class MainActivity extends BaseActivity {private WindowManager mWindowManager;private WindowManager.LayoutParams param;private ImageView mLayout;private Handler mHandler = new Handler(){@Overridepublic void handleMessage(Message msg) {super.handleMessage(msg);switch (msg.what){case FloatView.CLICK:Logger.d("收到click,开始清理垃圾");//属性动画--旋转Animator animator = AnimatorInflater.loadAnimator(MainActivity.this,R.animator.property_animator);animator.setTarget(mLayout);animator.start();break;}}};@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);Logger.d("MainActivity--onCreate()");setContentView(R.layout.activity_main);/***Android6.0以上系统增加了权限管理,所以需要添加如下代码,来让用户选择打开桌面浮窗的权限*/if (Build.VERSION.SDK_INT >= 23) {if (! Settings.canDrawOverlays(MainActivity.this)) {Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,Uri.parse("package:" + getPackageName()));startActivityForResult(intent,10);}}showView();}@Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent data) {if (requestCode == 10) {if (Build.VERSION.SDK_INT >= 23) {if (!Settings.canDrawOverlays(this)) {// SYSTEM_ALERT_WINDOW permission not granted...Toast.makeText(MainActivity.this, "not granted", Toast.LENGTH_SHORT);}}}}private void showView(){mLayout=new FloatView(getApplicationContext(),mHandler);mLayout.setBackgroundResource(R.drawable.sun);//获取WindowManagermWindowManager=(WindowManager)getApplicationContext().getSystemService(Context.WINDOW_SERVICE);//设置LayoutParams(全局变量)相关参数param = ((MyApplication)getApplication()).getMywmParams();param.type=WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;// 系统提示类型,重要(These windows are always on top of application windows)param.format=1;param.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; // 表示Window不需要获取焦点param.flags = param.flags | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH;//可以监听MotionEvent的ACTION_OUTSIDE事件param.flags = param.flags | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS; // 排版限制--即允许在可见的屏幕之外param.alpha = 1.0f;param.gravity=Gravity.LEFT|Gravity.TOP;   //调整悬浮窗口至左上角//以屏幕左上角为原点,设置x、y初始值param.x=0;param.y=0;//设置悬浮窗口长宽数据param.width=140;param.height=140;//显示myFloatView图像mWindowManager.addView(mLayout, param);}@Overridepublic void onDestroy(){super.onDestroy();//在程序退出(Activity销毁)时销毁悬浮窗口mWindowManager.removeView(mLayout);}
}
package com.hongri.recyclerview.widget;import android.content.Context;
import android.os.Handler;
import android.os.Message;
import android.view.MotionEvent;
import android.view.WindowManager;
import android.widget.ImageView;import com.hongri.recyclerview.MyApplication;
import com.hongri.recyclerview.utils.Logger;/*** 自定义桌面悬浮image,添加拖动和点击事件*/
public class FloatView extends ImageView {private float mTouchStartX;private float mTouchStartY;private float x;private float y;private float beginX,endX,beginY,endY;private WindowManager wm=(WindowManager)getContext().getApplicationContext().getSystemService(Context.WINDOW_SERVICE);private WindowManager.LayoutParams wmParams = ((MyApplication)getContext().getApplicationContext()).getMywmParams();private Context context;private Handler mHandler;public static final int CLICK = 1;public FloatView(Context context, Handler mHandler) {super(context);this.context = context;this.mHandler = mHandler;}@Overridepublic boolean onTouchEvent(MotionEvent event) {//获取相对屏幕的坐标,即以屏幕左上角为原点x = event.getRawX();y = event.getRawY()/*-25*/;   //25是系统状态栏的高度switch (event.getAction()) {case MotionEvent.ACTION_DOWN://获取相对View的坐标,即以此View左上角为原点beginX = endX = mTouchStartX =  event.getX();beginY = endY = mTouchStartY =  event.getY();Logger.d("ACTION_DOWN");break;case MotionEvent.ACTION_MOVE:updateViewPosition();Logger.d("ACTION_MOVE");break;case MotionEvent.ACTION_UP:
//                updateViewPosition();Logger.d("ACTION_UP");endX = event.getX();endY = event.getY();if (endX - beginX == 0 && endY - beginY == 0){//点击事件Logger.d("点击事件");Message msg = Message.obtain();msg.what = CLICK;msg.obj = "点击事件";mHandler.sendMessage(msg);}else {//发生了拖拽Logger.d("发生了拖拽");}mTouchStartX=mTouchStartY=0;break;case MotionEvent.ACTION_OUTSIDE:Logger.d("ACTION_OUTSIDE");break;}return true;}private void updateViewPosition(){//更新浮动窗口位置参数wmParams.x=(int)( x-mTouchStartX);wmParams.y=(int) (y-mTouchStartY);Logger.d("x:"+x+" y:"+y);Logger.d("mTouchStartX:"+mTouchStartX+" mTouchStartY:"+mTouchStartY);wm.updateViewLayout(this, wmParams);}}
public class MyApplication extends Application {private WindowManager.LayoutParams wmParams=new WindowManager.LayoutParams();public WindowManager.LayoutParams getMywmParams(){return wmParams;}}

res/animator文件下的property_animator.xml(属性动画--旋转):

<set xmlns:android="http://schemas.android.com/apk/res/android"android:ordering="sequentially"><set android:ordering="together"><objectAnimatorandroid:duration="800"android:propertyName="rotation"android:valueFrom="0"android:valueTo="1080"android:valueType="floatType">
       </objectAnimator></set></set>

最后在AndroidManifest.xml文件中记得加上如下权限:

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

还有一点需要注意的是在6.0以上的系统中需要用户自己打开“显示悬浮窗”权限才能展示该应用的悬浮窗。

Android 悬浮窗的实现(类似于360加速球)相关推荐

  1. Android悬浮窗原理解析(Window)[源码]

    悬浮窗,在大多数应用中还是很少见的,目前我们接触到的悬浮窗,差不多都是一些系统级的应用软件,例如:360安全卫士,腾讯手机管家等:在某些服务行业如金融,餐饮等,也会在应用中添加悬浮窗,例如:美团的偷红 ...

  2. Android 悬浮窗功能的实现

    前言 我们大多数在两种情况下可以看到悬浮窗,一个是视频通话时的悬浮窗,另一个是360卫士的悬浮球,实现此功能的方式比较多,这里以视频通话悬浮窗中的需求为例.编码实现使用Kotlin.Java版本留言邮 ...

  3. Android 悬浮窗,绝对是目前相关悬浮窗开源库最完美的适配方案

    PerfectFloatWindow 项目地址:Alonsol/PerfectFloatWindow 简介: android 全局悬浮窗,目前已经适配华为,小米,vivo,oppo,一加,三星,魅族, ...

  4. Android悬浮窗

    今天给大家写一个这个Android悬浮窗的功能,这个功能一般在360,酷狗(桌面歌词),网易云音乐(桌面歌词)上面用到,一般开发是很少碰到这个功能的,但是这个悬浮窗功能可以帮助理解Android的绘制 ...

  5. android悬浮窗语音识别demo

    带有android悬浮窗的语音识别语义理解demo 如发现代码排版问题,请访问CSDN博客 Android桌面悬浮窗实现比较简单,本篇以一个语音识别,语义理解的demo来演示如何实现android悬浮 ...

  6. Android悬浮窗的简单实现

    1. 前言 现在很多应用都有小悬浮窗的功能,比如看直播的时候,通过Home键返回桌面,直播的小窗口仍可以在屏幕上显示.下面将介绍下悬浮窗的的一种简单实现方式. 2.原理 Window我们应该很熟悉,它 ...

  7. Android悬浮窗的实现

    Android悬浮窗的实现 *本篇文章已授权微信公众号 guolin_blog (郭霖)独家发布 本文也发布于本人的知乎文章:https://zhuanlan.zhihu.com/p/39421112 ...

  8. 安卓java浮层不响应点击事件,Android悬浮窗屏蔽悬浮窗外部所有的点击事件的实例代码...

    Android可以在所有应用上方添加View,就是给WindowManager添加一个View,在创建的View的时候可以给这个View设置LayoutParams(android.view.Wind ...

  9. Android展开悬浮窗功能,Android 悬浮窗 (附圆形菜单悬浮窗)

    序言 Android悬浮窗的实现,主要有四个步骤: 1. 声明及申请权限 2. 构建悬浮窗需要的控件 3. 将控件添加到WindowManager 4. 必要时更新WindowManager的布局 一 ...

  10. android动态获取悬浮窗,Android 悬浮窗实现

    Android悬浮窗实现中需要注意的两点是 1.Android 6.0之后的悬浮窗动态申请 2.Window 的type属性在Android8.0前后的适配 public abstract class ...

最新文章

  1. 七彩岁月【我与51CTO一“七”成长】
  2. Semi-sync master failed on net_flush() before wait
  3. 栈----生产者消费者实例
  4. SpringBoot 之集成 Spring AOP
  5. Wi-Fi 6到底有什么特别?
  6. win10 mysql 驱动无法使用吗_Windows10驱动无法使用是怎么回事
  7. Linux(Centos7)下使用RPM方式安装MySQL5.7
  8. 图片异步加载框架 Android-Universal-Image-Loader
  9. (转)AssetBundle系列——游戏资源打包(二)
  10. 大数据入门:Hadoop大数据开发核心讲解
  11. html如何设置整体字体颜色,html字体颜色 html如何设置字体颜色
  12. 实验室信息化管理系统LIMS手机端二维码应用
  13. 迪赛智慧数——柱状图(多色柱状图):母亲节大家都怎么挑选礼物
  14. 小闹乎谈新手必备的撸猫手册
  15. 【从零开始的Java开发】1-5-4 ArrayList、HashSet、HashMap 概述与案例
  16. 【python爬虫实战】 001 技术路线图
  17. 计算机无法登录到你的账户,win10电脑无法登陆到你的账户怎么办?win10电脑无法登陆到你的账户相关讲解...
  18. CF14E Camels
  19. 医院考勤签到系统设计与实现
  20. 阿里云王文彬:希望云计算支撑百亿设备

热门文章

  1. oracle空间查询
  2. Hive的下载和安装
  3. (IoT物联网)天线的设计步骤 - 完整收藏版
  4. 华为交换机配置远程连接
  5. java Guide 面试指南
  6. AB_PLC编程软件RSLogix_500_与PLC通讯详细说明
  7. mysql用alter创建外键_MySQL入门(alter语法 与 外键)
  8. 清理C盘空间,给Win7释放更多C盘容量
  9. 在linux中查看服务,linux中怎么查看服务状态
  10. 一卡通管理系统服务器,一卡通管理系统