效果图

原理

获取windowManager 设定WindowManager.LayoutParams使窗口悬浮
主要涉及的值如下,其中

params.type = WindowManager.LayoutParams.TYPE_APPLICATION;

设置悬浮窗在应用内,在弹出dialog会悬浮在dialog下方,如果将这个值设置为TYPE_PHONE那么会悬浮在屏幕最上方,回到桌面后,如果应用没有退出悬浮球还是会出现在桌面上,所以如果要开发桌面悬浮球可以这样设置。

    WindowManager.LayoutParams params;params = new WindowManager.LayoutParams();params.type = WindowManager.LayoutParams.TYPE_APPLICATION;params.format = PixelFormat.TRANSLUCENT;params.flags = WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE|WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS;params.gravity = Gravity.LEFT | Gravity.TOP;params.width = viewWidth;params.height = viewHeight;params.x = 0;params.y = screenHeight / 3;windowManager.addView(*****,params);

代码

import android.content.Context;
import android.graphics.PixelFormat;
import android.os.Build;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.view.Display;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;
import android.widget.LinearLayout;import java.lang.reflect.Field;
import java.lang.reflect.Method;/*** Created by fanweichao on 2016/9/6.*/
public class FloatView extends LinearLayout {private Context mContext;private WindowManager windowManager;private View floatView;public int viewWidth;public int viewHeight;private  WindowManager.LayoutParams params;private float xInScreen;private float yInScreen;private float xInView;private float yInView;private int screenWidth;private int screenHeight;private static int historyX = 0;private static int historyY = 0;private static float historyAlpha = 1;
//    private static int historyVisible = VISIBLE;private static String histotyOritation;private Runnable mHideHalfCallback;/*** 记录手指按下时在屏幕上的横坐标的值*/private float xDownInScreen;/*** 记录手指按下时在屏幕上的纵坐标的值*/private float yDownInScreen;/*** 状态栏的高度*/private int statusBarHeight;private OnFloatViewClickListener onFloatViewClickListener;public FloatView(Context context) {this(context,null);}public FloatView(Context context, AttributeSet attrs) {super(context, attrs);mContext = context;init();}private void init() {viewWidth = Utils.dip2px(mContext,50);viewHeight = Utils.dip2px(mContext,50);windowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);screenWidth = windowManager.getDefaultDisplay().getWidth();screenHeight = windowManager.getDefaultDisplay().getHeight();floatView = View.inflate(mContext,R.layout.******,this);params = new WindowManager.LayoutParams();params.type = WindowManager.LayoutParams.TYPE_APPLICATION;params.format = PixelFormat.TRANSLUCENT;params.flags = WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE|WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS;params.gravity = Gravity.LEFT | Gravity.TOP;params.width = viewWidth;params.height = viewHeight;setViewAlpha(historyAlpha);if (historyX == 0 && historyY == 0){params.x = 0;params.y = screenHeight / 3;}else {if (historyX >screenWidth-viewWidth/2 || historyY >screenHeight -viewHeight/2){params.x = 0;params.y = screenHeight / 3;historyX = params.x;historyY = params.y;}else {params.x = historyX;params.y = historyY;}}windowManager.addView(this,params);
//        setVisibility(historyVisible);}@Overridepublic boolean onTouchEvent(MotionEvent event) {
//        screenWidth = windowManager.getDefaultDisplay().getWidth();
//        screenHeight = windowManager.getDefaultDisplay().getHeight();switch (event.getAction()){case MotionEvent.ACTION_DOWN:setViewAlpha(1);removeCallbacks(mHideHalfCallback);xInScreen = event.getRawX();yInScreen = event.getRawY() - getStatusBarHeight();xDownInScreen = event.getRawX();yDownInScreen = event.getRawY() - getStatusBarHeight();xInView = event.getX();yInView = event.getY();break;case MotionEvent.ACTION_MOVE:xInScreen = event.getRawX();yInScreen = event.getRawY() - getStatusBarHeight();updateViewPosition();break;case MotionEvent.ACTION_UP://计算位置并靠边if (Math.abs(xDownInScreen-xInScreen)<20 && Math.abs(yDownInScreen-yInScreen)<20){//单击事件if (null != onFloatViewClickListener){onFloatViewClickListener.onFloatViewClick();}}stepAside();break;}return true;}private void stepAside() {int  inWitchSide = 0;float viewCenterX = params.x + viewWidth/2;float viewCenterY = params.y + viewHeight/2;
//        screenWidth = windowManager.getDefaultDisplay().getWidth();
//        screenHeight = windowManager.getDefaultDisplay().getHeight();float dxLeft = viewCenterX;float dyUp = viewCenterY;float dxRight  = screenWidth - dxLeft;float dyDown = screenHeight -dyUp;float result = getMin(dxLeft,dyUp,dxRight,dyDown);if (result == dxLeft){params.x = 0;inWitchSide = 0;}else if (result == dxRight){params.x = screenWidth-viewWidth;inWitchSide = 1;}else if (result == dyUp){params.y = 0;inWitchSide = 2;}else{params.y = screenHeight-viewHeight-getStatusBarHeight();inWitchSide = 3;}windowManager.updateViewLayout(this, params);historyX = params.x;historyY = params.y;hideHalf(inWitchSide);}private void hideHalf(final int inWitchSide) {mHideHalfCallback = new HideHalfCallback(inWitchSide);postDelayed(mHideHalfCallback,1000);}private void updateViewPosition() {params.x = (int) (xInScreen - xInView);params.y = (int) (yInScreen - yInView);if (params.x <0){params.x = 0;}if (params.y < 0){params.y  = 0;}if ((params.x + viewWidth) > screenWidth){params.x = screenWidth -viewWidth;}if (params.y + viewHeight > screenHeight -getStatusBarHeight()){params.y = screenHeight - getStatusBarHeight() -viewHeight;}windowManager.updateViewLayout(this, params);historyX = params.x;historyY = params.y;}private int getStatusBarHeight() {if (statusBarHeight == 0) {try {Class<?> c = Class.forName("com.android.internal.R$dimen");Object o = c.newInstance();Field field = c.getField("status_bar_height");int x = (Integer) field.get(o);statusBarHeight = getResources().getDimensionPixelSize(x);} catch (Exception e) {e.printStackTrace();}}return statusBarHeight;}private float getMin(float dxLeft, float dyUp, float dxRight, float dyDown){float a = Math.min(dxLeft,dyUp);float b = Math.min(dxRight,dyDown);float c = Math.min(a,b);return c;}public   int getBottomStatusHeight(Context context){int totalHeight = getDpi(context);int contentHeight = getScreenHeight(context);return totalHeight  - contentHeight;}//获取屏幕原始尺寸高度,包括虚拟功能键高度public  int getDpi(Context context){int dpi = 0;WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);Display display = windowManager.getDefaultDisplay();DisplayMetrics displayMetrics = new DisplayMetrics();@SuppressWarnings("rawtypes")Class c;try {c = Class.forName("android.view.Display");@SuppressWarnings("unchecked")Method method = c.getMethod("getRealMetrics",DisplayMetrics.class);method.invoke(display, displayMetrics);dpi=displayMetrics.heightPixels;}catch(Exception e){e.printStackTrace();}return dpi;}public  int getScreenHeight(Context context){WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);DisplayMetrics outMetrics = new DisplayMetrics();wm.getDefaultDisplay().getMetrics(outMetrics);return outMetrics.heightPixels;}public  int getScreenWidth(Context context){WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);DisplayMetrics outMetrics = new DisplayMetrics();wm.getDefaultDisplay().getMetrics(outMetrics);return outMetrics.widthPixels;}public void showView(){windowManager.addView(this,params);}public void setOnFloatViewClickListener(OnFloatViewClickListener onFloatViewClickListener) {this.onFloatViewClickListener = onFloatViewClickListener;}public interface OnFloatViewClickListener{void onFloatViewClick();}public void removeView(){try {windowManager.removeView(this);}catch (Exception e){}removeCallbacks(mHideHalfCallback);mHideHalfCallback = null;windowManager = null;params = null;}public void setViewAlpha(float f){if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {setAlpha(f);historyAlpha = f;}}private class HideHalfCallback implements Runnable{int inWitchSide;public HideHalfCallback(int inWitchSide){this.inWitchSide = inWitchSide;}@Overridepublic void run() {if (null != params && null != windowManager){if (inWitchSide == 0){params.x = -viewWidth/2;}else if (inWitchSide == 1){params.x = screenWidth-viewWidth/2;}else if (inWitchSide == 2){params.y = -viewHeight/2;}else if (inWitchSide == 3){params.y =  screenHeight - viewHeight/2 - getStatusBarHeight();}windowManager.updateViewLayout(FloatView.this, params);setViewAlpha(0.5f);historyX = params.x;historyY = params.y;}}}@Overridepublic void setVisibility(int visibility) {super.setVisibility(visibility);
//        historyVisible = visibility;}
}

【android】悬浮球相关推荐

  1. android 悬浮球简书,轻松自制flyme悬浮球

    前言 去年用了一整年的MX4Pro,魅族留给我最大的印象就是悬浮球了(质量问题我就不说了),左右滑动切换应用.上拉返回桌面.下拉打开通知栏.轻触返回...,一切都那么丝滑.然而自从上半年换成了s7de ...

  2. Android悬浮球及全局返回功能的实现

    先来一发效果图: 前面是返回效果,最后一下是实现home键的效果 前言 很久之前,就想做一个悬浮球了,毕竟是程序猿嘛,有想要的功能的时候总是想自己尝试一下,于是兴致勃勃的找了好久,都没有找到全局返回功 ...

  3. android悬浮球代码,Android 仿360悬浮球与加速球

    先来看一张动态图 昨天跟着视频学了如何自定义View并做成仿360悬浮球与加速球的样式 可以看出来,做成的效果有: 点击按钮后退出Activity,呈现一个圆形的悬浮球,可以随意拖动并会自动依靠到屏幕 ...

  4. android 悬浮球动画,Android 仿360悬浮球与加速球

    先来看一张动态图 昨天跟着视频学了如何自定义View并做成仿360悬浮球与加速球的样式 可以看出来,做成的效果有: 点击按钮后退出Activity,呈现一个圆形的悬浮球,可以随意拖动并会自动依靠到屏幕 ...

  5. android 悬浮球代码,Android 悬浮球

    闲来无事,搞一波悬浮球,此球: 无需权限 主要代码只有一个类,简简单单放进自己的工程 悬浮球可以用来干啥: 打开侧滑界面 打开一排小按钮 打开客服等等 功能: 显示红点(接收到信息等场景) 关闭红点( ...

  6. android悬浮球截屏,vivoX27怎么双击悬浮球截屏?获取屏幕截图依旧方便快速!

    在此前一段时间中,iphone手机有一项功能在抖音中非常的火爆,那就是双击iphone的小白点进行截图的功能,让你不再依赖于截屏快捷键或是实体快捷键也能进行轻松的截图. 而今天我们要说的,是vivoX ...

  7. android悬浮球截屏,ColorOS7的悬浮球截屏和长截屏怎么用,有哪些方式

    11月20日OPPO官方发布了这个全新的ColorOS 7系统了,在发布会上展现了很多惊艳的功能,但是对于操作便捷来说,我最喜欢的还是截屏方式的改变,变得花样更多了,相信这个截屏在大家使用手机的过程中 ...

  8. Android TV 悬浮球模拟物理按键

      最近在体验实习的时候做了一个TV的内存管家,其中有个要求是实现一个悬浮球,模拟TV控制器的按键,实现上下左右,back,menu,home等效果,并且做一个火箭升空的效果.这时候才发现网上有关tv ...

  9. android 悬浮按钮 魅族,魅族,我的悬浮球功能比你的强大:悬浮菜单

    Android 上的小圆点应用比比皆是,最近魅族也在 Flyme 4.1 中加入了悬浮球功能.本来对这类应用也是倦了,但想试试无妨.经过几天的使用,感觉悬浮菜单特别就特别在功能非常全面,一个应用就能搞 ...

  10. android system webview diable,FV悬浮球橡皮泥主题

    FV悬浮球橡皮泥主题,一款悬浮球窗口皮肤工具.下载后安装FV悬浮球和橡皮泥主题打开侧边主题,即可自由切换悬浮球皮肤,支持墨水屏主题和暗黑主题适配,需要的朋友点击下载吧. 安装说明: 仅用于FV悬浮球. ...

最新文章

  1. linux webrtc浏览器,WebRTC 浏览器支持
  2. android jsoup简书,jsoup爬虫简书首页数据做个小Demo
  3. 多个客户端抢夺命名管道_使用Kafka构建数据管道
  4. iOS Block 知识点拾遗
  5. 2019年1月16日【第三天学习】
  6. oracle中的自带函数,求完整的ORACLE自带函数文档
  7. c语言long说明符,C语言-类型说明符 long,short,unsigned,signed
  8. Android TTS 自动发声
  9. 【教3妹学算法-每日3题(2)】分割字符串的最大得分
  10. Django 修改时区时间
  11. 自学 iOS 开发的一些经验
  12. exoplay切换全屏_02.视频播放器整体结构
  13. 2023 CVTE寒暑假实习C++开发 笔试一面面经
  14. 图片识别项目 是商品包装识别分类
  15. C++实现骰子涂色算法
  16. .NetCore框架Surging系列(六)路由发现
  17. miniui页面移动的时候透明_PPT中「透明度」功能,根本想不到还能这样用
  18. 数据平面开发套件:DPDK
  19. php 如果有 截取,PHP 字符串截取
  20. 关于zebra中thread的解析

热门文章

  1. SAS实验04 ——回归分析
  2. 奥维 最新 图源2023
  3. UUP, Windows 11 更新机制的未来
  4. 京东JD App签名/加密算法研究
  5. html2canvas图片的文字偏移,html2canvas在Vue项目踩坑-生成图片偏移不完整
  6. rust fragment specifier
  7. HTML无序列表四大名著
  8. Tomcat跨域配置
  9. 1.1.4实践环节--制作调查问卷
  10. Nginx官方文档(四十七)【ngx_stream_js_module|ngx_stream_keyval_module|ngx_stream_limit_conn_module】