今天我们接着昨天的继续
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:需要源码的请留意哦