用过iphone的朋友都知道,iPhone有个圆球辅助工具,它漂浮在你的手机屏幕(在任何APP之上),你可以将它移动到任何地方,它叫做AssistiveTouch,本篇模拟该软件实现一个小案例,主要是实现它的界面,首先来看看实现的效果吧:

拖动小圆球:

点击弹出pop窗口:

为了让辅助工具一直悬浮在窗口之上,这里使用的机制是通过在程序初始化是,启动一个service,在service的onCreate() 函数中使用LayoutInflater来加载一个view,而这个view就是辅助球的布局文件:floatball.xml,然后对它进行onclick事件的监听,setOnClickListener监听到辅助球点击事件之后,就创建一个PopupWindow,弹出如上的菜单界面,大体的实现就是这样。

其实,实现窗口悬浮于最前面的一个重要属性是:WindowManager.LayoutParams.TYPE_PHONE

我们只要将WindowManager.LayoutParams的type属性设置为 WindowManager.LayoutParams.TYPE_PHONE就可以实现悬浮最前面。

工程目录结构:

部分代码解析:

MyApplication.java:

package com.tyd.floatball.util;
import android.app.Application;
import android.view.WindowManager;
public class MyApplication extends Application {  private WindowManager.LayoutParams wmParams = new WindowManager.LayoutParams();  public WindowManager.LayoutParams getMywmParams() {  return wmParams;  }
}  

MainActivity.java:

package com.tyd.floatball.ui;  import com.tyd.floatball.R;
import com.tyd.floatball.R.layout;
import com.tyd.floatball.service.TopFloatService;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;  public class MainActivity extends Activity {  @Override  public void onCreate(Bundle savedInstanceState) {  super.onCreate(savedInstanceState);  setContentView(R.layout.main);  Intent service = new Intent();  service.setClass(this, TopFloatService.class);  //启动服务  startService(service);  }
}  

TopFloatService.java:

package com.tyd.floatball.service;  import android.app.Service;
import android.content.Intent;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.graphics.drawable.BitmapDrawable;
import android.os.IBinder;
import android.util.DisplayMetrics;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnKeyListener;
import android.view.View.OnTouchListener;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.PopupWindow;
import android.widget.RelativeLayout;
import android.widget.Toast;
import com.tyd.floatball.R;
import com.tyd.floatball.util.MyApplication;  public class TopFloatService extends Service implements OnClickListener,OnKeyListener{  WindowManager wm = null;  WindowManager.LayoutParams ballWmParams = null;  private View ballView;  private View menuView;  private float mTouchStartX;  private float mTouchStartY;  private float x;  private float y;  private RelativeLayout menuLayout;  private Button floatImage;  private PopupWindow pop;  private RelativeLayout menuTop;  private boolean ismoving = false;  @Override  public void onCreate() {  super.onCreate();  //加载辅助球布局  ballView = LayoutInflater.from(this).inflate(R.layout.floatball, null);  floatImage = (Button)ballView.findViewById(R.id.float_image);  setUpFloatMenuView();  createView();  }  /**  * 窗口菜单初始化  */  private void setUpFloatMenuView(){  menuView = LayoutInflater.from(this).inflate(R.layout.floatmenu, null);  menuLayout = (RelativeLayout)menuView.findViewById(R.id.menu);  menuTop = (RelativeLayout)menuView.findViewById(R.id.lay_main);  menuLayout.setOnClickListener(this);  menuLayout.setOnKeyListener(this);  menuTop.setOnClickListener(this);  }  /**  * 通过MyApplication创建view,并初始化显示参数  */  private void createView() {  wm = (WindowManager) getApplicationContext().getSystemService("window");  ballWmParams =  ((MyApplication) getApplication()).getMywmParams();  ballWmParams.type = WindowManager.LayoutParams.TYPE_PHONE;  ballWmParams.flags |= WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;  ballWmParams.gravity = Gravity.LEFT | Gravity.TOP;  ballWmParams.x = 0;  ballWmParams.y = 0;  ballWmParams.width = WindowManager.LayoutParams.WRAP_CONTENT;  ballWmParams.height = WindowManager.LayoutParams.WRAP_CONTENT;  ballWmParams.format = PixelFormat.RGBA_8888;  //添加显示层  wm.addView(ballView, ballWmParams);  //注册触碰事件监听器  floatImage.setOnTouchListener(new OnTouchListener() {  public boolean onTouch(View v, MotionEvent event) {  x = event.getRawX();  y = event.getRawY();   switch (event.getAction()) {  case MotionEvent.ACTION_DOWN:  ismoving = false;  mTouchStartX = (int)event.getX();  mTouchStartY = (int)event.getY();  break;  case MotionEvent.ACTION_MOVE:  ismoving = true;  updateViewPosition();  break;  case MotionEvent.ACTION_UP:  mTouchStartX = mTouchStartY = 0;  break;  }  //如果拖动则返回false,否则返回true  if(ismoving == false){  return false;  }else{  return true;  }  }  });  //注册点击事件监听器  floatImage.setOnClickListener(new View.OnClickListener() {  @Override  public void onClick(View v) {  DisplayMetrics dm = getResources().getDisplayMetrics();  pop = new PopupWindow(menuView, dm.widthPixels, dm.heightPixels);  pop.showAtLocation(ballView, Gravity.CENTER, 0, 0);  pop.update();  }  });  }  /**  * 更新view的显示位置  */  private void updateViewPosition() {  ballWmParams.x = (int) (x - mTouchStartX);  ballWmParams.y = (int) (y - mTouchStartY);  wm.updateViewLayout(ballView, ballWmParams);  }  @Override  public IBinder onBind(Intent intent) {  return null;  }  @Override  public void onClick(View v) {  switch (v.getId()) {  case R.id.lay_main:  Toast.makeText(getApplicationContext(), "111", 1000).show();  break;  default:  if(pop!=null && pop.isShowing()){  pop.dismiss();  }  break;  }  }  @Override  public boolean onKey(View v, int keyCode, KeyEvent event) {  Toast.makeText(getApplicationContext(), "keyCode:"+keyCode, 1000).show();  switch (keyCode) {  case KeyEvent.KEYCODE_HOME:  pop.dismiss();  break;  default:  break;  }  return true;  }  } 

辅助球的布局文件 floatball.xml:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"  android:layout_width="match_parent"  android:layout_height="wrap_content"  android:orientation="vertical"  android:layout_gravity="center_vertical">  <Button  android:id="@+id/float_image"  android:layout_width="50dp"  android:layout_height="50dp"  android:background="@drawable/selector_btn_assistive"   />  </FrameLayout>  

窗口菜单的布局文件floatmenu.xml:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  android:id="@+id/menu"  android:layout_width="fill_parent"  android:layout_height="fill_parent"  android:background="@drawable/transparent" >  <LinearLayout  android:layout_width="@dimen/size_dialog"  android:layout_height="@dimen/size_dialog"  android:layout_centerInParent="true"  android:background="@drawable/shape_background_assistivetouch"  android:orientation="vertical" >  <RelativeLayout  android:id="@+id/lay_main"  android:layout_width="fill_parent"  android:layout_height="fill_parent"  android:orientation="vertical"  android:padding="4.0px"  android:visibility="visible" >  <TextView  android:id="@+id/btn_apps"  style="@style/Icon"  android:layout_centerInParent="true"  android:drawableTop="@drawable/selector_ic_apps"  android:text="@string/apps" />  <TextView  android:id="@+id/btn_home_screen"  style="@style/Icon"  android:layout_alignParentBottom="true"  android:layout_centerHorizontal="true"  android:drawableTop="@drawable/selector_ic_home"  android:text="@string/home_screen" />  <TextView  android:id="@+id/btn_setting"  style="@style/Icon"  android:layout_alignParentRight="true"  android:layout_centerVertical="true"  android:drawableTop="@drawable/selector_ic_phone"  android:text="@string/setting" />  <TextView  android:id="@+id/btn_lock_screen"  style="@style/Icon"  android:layout_centerHorizontal="true"  android:drawableTop="@drawable/selector_ic_power_down"  android:text="@string/lock_screen" />  <TextView  android:id="@+id/btn_favor"  style="@style/Icon"  android:layout_alignParentLeft="true"  android:layout_centerVertical="true"  android:drawableTop="@drawable/selector_ic_star"  android:text="@string/favor" />  </RelativeLayout>  </LinearLayout>  </RelativeLayout> 

AndroidManifest.xml:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"  package="com.tyd.floatball"  android:versionCode="1"  android:versionName="1.0" >  <uses-sdk android:minSdkVersion="14" />  <application  android:icon="@drawable/ic_launcher"  android:label="@string/app_name"   android:name=".util.MyApplication">  <activity  android:label="@string/app_name"  android:name=".ui.MainActivity" >  <intent-filter >  <action android:name="android.intent.action.MAIN" />  <category android:name="android.intent.category.LAUNCHER" />  </intent-filter>  </activity>  <service   android:name=".service.TopFloatService"    android:enabled="true"  android:exported="true"  />  </application>  <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />  <uses-permission android:name="android.permission.DISABLE_KEYGUARD"/>
</manifest>

该实例我已经将源码整理打包,进行了上传,下面是资源的下载地址:

http://download.csdn.net/detail/wulianghuan/5364129

仿iphone快速导航悬浮球相关推荐

  1. android 仿iphone多任务管理效果,别羡慕苹果了,安卓悬浮神器比 iPhone 好用太多!...

    原标题:别羡慕苹果了,安卓悬浮神器比 iPhone 好用太多! 都 2021 年了,你还不知道安卓悬浮球是款神器? 就在不久前,小黑被友人如此嘲讽.作为一名经常接触数码科技的资深搞机党,小黑一直对悬浮 ...

  2. 苹果悬浮球_今天才发现!iPhone手机悬浮球这么好用!怪自己知道太晚了

    小屏iPhone SE2已经上市一个多月了,相信很多果粉已经换上了新机. 使用小屏iPhone,很多朋友都会开启悬浮球功能,也就是我们常说的"小白点". 因为小屏iPhone开启它 ...

  3. 苹果悬浮球_原来iPhone手机悬浮球这么厉害!开启后,能让手机变得更好用

    苹果手机是大家最喜欢的手机品牌之一,不仅是因为苹果手机流畅耐用,还是苹果手机使用起来很方便. 比如iPhone手机的悬浮球功能,也就常说的"小白点"就特别厉害!开启后,能让手机变得 ...

  4. Vue实现仿iPhone悬浮球

    Vue实现仿iPhone悬浮球 悬浮球插件简单的效果图: 很遗憾,没找到太好的视频转gif的软件,压缩出来的大小超过了限制,就不放图了 可以参考其他人的图,效果一致: 简单实用案例: <!-- ...

  5. html滑动仿悬浮球菜单

    html滑动仿悬浮球菜单 css样式 html代码 javascript代码 css样式 html,body{width: 100%;height: 100%;margin: 0;padding: 0 ...

  6. iOS:高仿微信文章悬浮球

    前言 微信在最新版本6.6.7,新加了一个文章悬浮球功能.当你正在阅读文章的时候,突然有好友发来了紧急消息,你需要立即回复.又或者你刚好路过小吃店,需要临时打开微信支付,等等临时中断阅读的情况.以前只 ...

  7. html设置悬浮效果,html滑动仿悬浮球菜单效果的实现-电脑自学网

    css样式 html,body{ width: 100%; height: 100%; margin: 0;padding: 0; } /*导航图标*/ .NMH-g-navicon{ positio ...

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

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

  9. HTML页面悬浮球,html滑动仿悬浮球菜单效果的实现

    这篇文章主要介绍了html滑动仿悬浮球菜单效果的实现,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下 css样式: html,body{ widt ...

最新文章

  1. Jzoj3907 蜀传之单刀赴会(梦回三国系列)
  2. mysql经典书籍--MySQL 必知必会
  3. 43.StrVec类:std::move调用移动构造函数的一个实例
  4. ReactNative-WebView组件
  5. Alex Hanna博士:Google道德AI小组研究员
  6. pipeline代码自动生成
  7. html5 视频 showtime,利用function showTime显示不出时间是为什么?
  8. mysql数据库服务器名_mysql数据库服务器名
  9. python 文本相似度现状_python文本相似度分析
  10. 36. In Depth Magento System Configuration
  11. mysql匿名账户登录导致的ERROR 1044 (42000): Access denied for user ''@'localhost' to database 'mysql'错误...
  12. C# Cron表达式解析 .net 项目文件
  13. 计蒜客 - 猴子打字
  14. 数据结构与算法邓俊辉——(二)
  15. 线性代数(预备知识)
  16. 多智能体系统编队算法仿真--python3实现
  17. 不能不懂的 Java 源代码编译过程分析
  18. 华南理工大学电气考研经验贴
  19. 蚂蚁金服通讯框架学习一
  20. python购物车结算不了_python中购物车

热门文章

  1. 中国区和市 js 文件
  2. Q群机器人--C语言零基础也能拥有
  3. win10系统老是自动重复,查看日志显示来源:DistributedCOM,事件:10016,解决办法
  4. 惠普暗影精灵II代 Pro电脑 Hackintosh 黑苹果efi引导文件
  5. 基于EKF的锂离子电池SOC估计——Simulink建模仿真
  6. C# 检测防火墙状态
  7. Java后台拦截淘宝口令并解析淘口令里面特殊字符的正则
  8. 小微权力监督平台功能列表:实现三资管理、大数据比对、监督举报等
  9. 隆云通空气温湿、CO2、PM2.5、光照五参数传感器
  10. 《不会吧?不会吧?不会还有人不知道 Markdown 吧?|CSDN编辑器测评》