仿iPhone assistivetouch小工具实现详解1

今天我们接着昨天的继续

1、实现控制球的点击拖动

2、点击控制球后弹出菜单选择界面

3、菜单选择功能

其实这几个都不难,思路如下:

1、要实现我们的控制球悬浮在所有App界面之上:通过WindowManager来设置App的显示方式

2、控制球的拖动:重写onTouchListener即可,这个相信很多人都做过了

3、弹出菜单界面和菜单选择功能:这个就是一个比较好看的PopupWindow

通过这几条分析,我们可以发现,这个项目其实还是比较简单的哈,所以说,我一直坚信的,思路很重要

下面我们一点点来实现吧:so easy

程序核心必然是一个Service,相信我不要多说了:

MainService:

package com.xys.xtouchassistant.service;

import com.xys.xtouchassistant.R;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.graphics.PixelFormat;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.os.IBinder;
import android.provider.Settings;
import android.util.DisplayMetrics;
import android.view.Gravity;
import android.view.LayoutInflater;
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 android.widget.PopupWindow;
import android.widget.TextView;
import android.widget.Toast;

public class MainService extends Service implements OnClickListener, OnTouchListener {

    // 控制球View
    private View touchBallView;
    // 弹出菜单View
    private View menuView;
    // 控制球
    private Button touchBall;
    // WindowManager
    WindowManager wm;
    // WindowManagerParams
    WindowManager.LayoutParams params;
    private PopupWindow popup;
    // 点击坐标
    private float x, y;
    private float touchX, touchY;
    // 移动Flag
    private boolean isMoving;
    // Menu上的组件
    private TextView tvApps;
    private TextView tvHomeScreen;
    private TextView tvSetting;
    private TextView tvLockScreen;
    private TextView tvFavor;

    @Override
    public void onCreate() {
	super.onCreate();
	// 初始化Views
	initView();
	// 显示TouchBall
	createTouchBallView();
	// 监听事件
	regListener();
    }

    /**
     * 监听事件
     */
    private void regListener() {
	touchBall.setOnTouchListener(this);
	touchBall.setOnClickListener(this);
	tvApps.setOnClickListener(this);
	tvHomeScreen.setOnClickListener(this);
	tvSetting.setOnClickListener(this);
	tvLockScreen.setOnClickListener(this);
	tvFavor.setOnClickListener(this);
    }

    /**
     * 初始化Views
     */
    private void initView() {
	// 加载控制球View
	touchBallView = LayoutInflater.from(this).inflate(R.layout.touch_ball, null);
	touchBall = (Button) touchBallView.findViewById(R.id.touch_ball);
	// 初始化MenuView
	menuView = LayoutInflater.from(this).inflate(R.layout.shown_menu, null);
	tvApps = (TextView) menuView.findViewById(R.id.tv_apps);
	tvHomeScreen = (TextView) menuView.findViewById(R.id.tv_home_screen);
	tvSetting = (TextView) menuView.findViewById(R.id.tv_setting);
	tvLockScreen = (TextView) menuView.findViewById(R.id.tv_lock_screen);
	tvFavor = (TextView) menuView.findViewById(R.id.tv_favor);
    }

    /**
     * 显示TouchBall
     */
    private void createTouchBallView() {
	wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
	params = new WindowManager.LayoutParams();
	params.type = WindowManager.LayoutParams.TYPE_PHONE;
	params.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
	params.gravity = Gravity.LEFT | Gravity.TOP;
	params.x = 0;
	params.y = 0;
	params.width = WindowManager.LayoutParams.WRAP_CONTENT;
	params.height = WindowManager.LayoutParams.WRAP_CONTENT;
	params.format = PixelFormat.RGBA_8888;
	wm.addView(touchBallView, params);
    }

    @Override
    public IBinder onBind(Intent intent) {
	return null;
    }

    @Override
    public void onClick(View v) {
	switch (v.getId()) {
	case R.id.touch_ball:
	    // 显示Popup菜单
	    showMenuWindow();
	    break;
	case R.id.tv_apps:
	    // 显示Apps菜单
	    Toast.makeText(this, "APPS", Toast.LENGTH_SHORT).show();
	    popup.dismiss();
	    break;
	case R.id.tv_favor:
	    Toast.makeText(this, "FAVOR", Toast.LENGTH_SHORT).show();
	    popup.dismiss();
	    break;
	case R.id.tv_home_screen:
	    // 显示主菜单
	    Toast.makeText(this, "HOME", Toast.LENGTH_SHORT).show();
	    popup.dismiss();
	    break;
	case R.id.tv_lock_screen:
	    // 锁屏
	    Toast.makeText(this, "LOCK", Toast.LENGTH_SHORT).show();
	    popup.dismiss();
	    break;
	case R.id.tv_setting:
	    // 显示Setting界面
	    Toast.makeText(this, "SETTING", Toast.LENGTH_SHORT).show();
	    popup.dismiss();
	    break;
	default:
	    popup.dismiss();
	    break;
	}
    }

    /**
     * 显示Popup菜单
     */
    private void showMenuWindow() {
	DisplayMetrics dm = getResources().getDisplayMetrics();
	popup = new PopupWindow(menuView, (int) (dm.widthPixels * 0.7), (int) (dm.heightPixels * 0.5));
	Drawable transpent = new ColorDrawable(Color.TRANSPARENT);
	popup.setBackgroundDrawable(transpent);
	popup.setFocusable(true);
	popup.setOutsideTouchable(true);
	popup.showAtLocation(touchBallView, Gravity.CENTER, 0, 0);
	popup.update();
    }

    /**
     * Touch监听事件
     */
    @Override
    public boolean onTouch(View v, MotionEvent event) {
	x = event.getRawX();
	y = event.getRawY();
	// 触摸事件
	switch (event.getAction()) {
	case MotionEvent.ACTION_DOWN:
	    isMoving = false;
	    // 触摸坐标赋值
	    touchX = event.getX();
	    touchY = event.getY();
	    break;
	case MotionEvent.ACTION_MOVE:
	    isMoving = true;
	    // 触摸坐标赋值
	    params.x = (int) (x - touchX);
	    params.y = (int) (y - touchY);
	    wm.updateViewLayout(touchBallView, params);
	    break;
	case MotionEvent.ACTION_UP:
	    // 触摸坐标赋值
	    touchX = touchY = 0;
	    break;
	default:
	    break;
	}
	if (isMoving) {
	    return true;
	} else {
	    return false;
	}
    }
}

开启Service的主程序:

MainActivity:

package com.xys.xtouchassistant.activity;

import com.xys.xtouchassistant.R;
import com.xys.xtouchassistant.service.MainService;
import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
	super.onCreate(savedInstanceState);
	setContentView(R.layout.activity_main);
	Intent service = new Intent();
	service.setClass(this, MainService.class);
	startService(service);
    }
}

这里只是简单的用一个Activity去开启这个服务,后面我们会重新实现开启服务的方法:

1、通过注册一个开机广播事件去开启我们的服务

2、通过进程守护来实现我们的Service不被kill(也可以通过在通知面板显式显示服务的方式来防止被kill)

3、实现菜单界面功能的可配置化

ps:需要源码的请留意哦

时间: 2024-10-18 20:20:44

仿iPhone assistivetouch小工具实现详解1的相关文章

仿iPhone assistivetouch小工具实现详解0

大家都知道iPhone下的assistivetouch这个小圆点 对,就是这个玩意儿 但是Android上没这玩意儿,所有今天我们就给Android上弄上一个这个玩意儿 看见没,和iPhone下的基本一样吧 我准备分几次讲这个项目的开发实例写出来,照例,今天搞定界面: 1.控制球界面 2.菜单界面 这些都不难,大家看下就懂了 控制球界面: <?xml version="1.0" encoding="utf-8"?> <FrameLayout xml

PowerShell攻防进阶篇:nishang工具用法详解

本文讲的是PowerShell攻防进阶篇:nishang工具用法详解, 1.简介 Nishang是一款针对PowerShell的渗透工具.说到渗透工具,那自然便是老外开发的东西.国人开发的东西,也不是不行,只不过不被认可罢了.不管是谁开发的,既然跟渗透有关系,那自然是对我们有帮助的,学习就好.来源什么的都不重要.总之,nishang也是一款不可多得的好工具.非常的好用. 2.简单的安装与问题处理   先到github上去下载nishang,可以使用git命令直接下载,如果没有装的话下载zip文件

AngularJS tab栏实现和mvc小案例实例详解

tab栏: 代码: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Tab 标签</title> <style> body { margin: 0; padding: 0; background-color: #F7F7F7; } .tabs { width: 400px; margin: 3

网络抓包工具Fiddler详解s

简介: Fiddler是一款网络分析工具,功能强大,下边介绍下他里边的工具栏以及他的使用方式. 工具栏介绍: 看下图: 打开以后就是这样一个界面. 然后介绍工具栏的选项: File :  里边包含了几个选项 Capture Traffic --启用捕获功能,快捷键 F12 此功能的开启/关闭状态,程序安装后默认是开启的.可以在 Fiddler 底部状态栏最左侧看到:(开启状态).(关闭状态) 也可以通过鼠标点击状态栏该图标来进行切换. Load Archive... --载入本地保存的 Sess

MongoDB运行状态监控、性能分析工具mongostat详解_MongoDB

这篇文章的目的是让你知道怎么了解你正在运行的Mongdb是否健康. mongostat详解 mongostat是mongdb自带的状态检测工具,在命令行下使用.它会间隔固定时间获取mongodb的当前运行状态,并输出.如果你发现数据库突然变慢或者有其他问题的话,你第一手的操作就考虑采用mongostat来查看mongo的状态. 它的输出有以下几列: 1.inserts/s 每秒插入次数 2.query/s 每秒查询次数 3.update/s 每秒更新次数 4.delete/s 每秒删除次数 5.

Web性能压力测试工具——Siege详解

Siege是一款开源的压力测试工具,设计用于评估WEB应用在压力下的承受能力.可以根据配置对一个WEB站点进行多用户的并发访问,记录每个用户所有请求过程的相应时间,并在一定数量的并发访问下重复进行. Siege可以从您选择的预置列表中请求随机的URL.所以siege可用于仿真用户请求负载,而ab则不能.但不要使用siege来执行最高性能基准调校测试,这方面ab就准确很多. 一.安装 编译安装 wget http://www.joedog.org/pub/siege/siege-latest.ta

Lua包管理工具Luarocks详解

摘要: 1. 什么是Luarocks 2. 源码安装部署Luarocks 3. 注册Luarocks为Lua社区贡献自己的代码 4. Luarocks使用初探 讨论话题 什么是Luarocks 源码安装部署Luarocks 注册Luarocks为Lua社区贡献自己的代码 Luarocks使用初探 什么是Luarocks Luarocks是一个Lua包管理器,基于Lua语言开发,提供一个命令行的方式来管理Lua包依赖.安装第三方Lua包等,社区比较流行的包管理器之一,另还有一个LuaDist,Lu

linux中Axel多线程下载工具参数详解

Axel安装 Debian/Ubuntu/Linux Mint用户  代码如下 复制代码 sudo apt-get install axel Redhat/Fedora 用户可用下面命令安装:  代码如下 复制代码 yum install axel 同样,大家可以源码编译安装:  代码如下 复制代码 cd ~/Download wget http://alioth.debian.org/frs/download.php/3015/axel-2.4.tar.gz tar zxvf axel-2.4

android内存泄露分析工具MAT详解

一.准备 1.什么是MAT Eclipse提供的一个内存分析工具.它是一个功能丰富的 JAVA 堆转储文件分析工具,可以帮助你发现内存漏洞和减少内存消耗. android studio未集成该插件 需要你下载独立版 android studio的DDMS可以生成hprof是什么文件,不过需要进行一下格式转化(.hprof文件从Dalvik格式转换成J2SE HPROF格式),才可以导入MAT独立版软件. 2.hprof是什么文件 heap dumps,中文翻译,堆转储,快照.即堆内存某个时刻的情