1.通过手指滑动位置 画操纵杆
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN ||
event.getAction() == MotionEvent.ACTION_MOVE) {
if(isLock){
return true;
}
final double dist = Math.sqrt(Math.pow((mCenterX - (int) event.getX()), 2)
+ Math.pow((mCenterY - (int) event.getY()), 2));
Log.d("TAG", "onTouchEvent: " + event.getY() + " SmallRockerCircleY:" + SmallRockerCircleY + " cicrlY/2 :" +- (cicrlY/2 - mRadius/2));
if (dist <= mRadius + ADD_DIST) {
//得到摇杆与触屏点所形成的角度
//保证内部小圆运动的长度限制
if (dist > mRadius) {
double tempRad = getRad(mCenterX, mCenterY, event.getX(), event.getY());
getXY(mCenterX, mCenterY, mRadius, tempRad);
Log.d("TAG", "isShowLock000" + " SmallRockerCircleX:" + SmallRockerCircleX + " mCenterX:" + mCenterX);
if (SmallRockerCircleX < mCenterX + 15 && SmallRockerCircleX > mCenterX - 15) {
Log.d("TAG", "isShowLock000" + isShowLock);
if(isShowLock){
Log.d("TAG", "isShowLock2222 isLockView.invalidate()" + (-(cicrlY/2 - mRadius/2)) + " SmallRockerCircleY:" + SmallRockerCircleY);
if(event.getY() > - 15 - (cicrlY/2 - mRadius/2) && event.getY() < 15 - (cicrlY/2 - mRadius/2)){
isLockView.setImageBitmap(lockBitmap);
isLockView.invalidate();
Log.d("TAG", "isShowLock2222 isLockView.invalidate()" );
isLock = true;
return true;
}
}else {
if(disposable == null){
disposable = Flowable.timer(1, TimeUnit.SECONDS)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Consumer
@Override
public void accept(Long aLong) throws Exception {
Log.e("TAG", "isShowLock1111" + isShowLock);
if(SmallRockerCircleX < mCenterX + 10 && SmallRockerCircleX > mCenterX - 10 && dist > mRadius){
isShowLock = true;
Log.e("TAG", "isShowLock2222" + isShowLock);
invalidate();
//postInvalidate();
}
}
});
}
}
}else {
if(isShowLock){
}else {
if(disposable != null){
disposable.dispose();
disposable = null;
}
isShowLock = false;
}
}
} else {
if(disposable != null){
disposable.dispose();
disposable = null;
}
isShowLock = false;
SmallRockerCircleX = (int) event.getX();
SmallRockerCircleY = (int) event.getY();
}
} else {//如果小球中心点小于活动区域则随着用户触屏点移动即可
return true;
}
//根据两点间距离和角度来判断运动方向
//330~30 右 30~60 右下 60~120 下 120~150 左下 150-210 左 210~240 左上 240~300 上 300~330 右上
Log.d("TAG", "onTouchEvent 4444" + "SmallRockerCircleX:" + SmallRockerCircleX + " SmallRockerCircleY:" + SmallRockerCircleY + " mRadius:" + mRadius);
if (Math.sqrt(Math.pow((mCenterX - SmallRockerCircleX), 2)
+ Math.pow((mCenterY - SmallRockerCircleY), 2)) > 0) {
Log.d("TAG", " mCenterX:" + mCenterX + " mCenterY:" + mCenterY + "getWidth" + getWidth());
float evetX = event.getX();
float eventY = event.getY();
float dx = Math.abs(evetX - mCenterX);
float dy = Math.abs(eventY - mCenterY);
double tempRad = getRad(mCenterX, mCenterY, evetX, eventY);
//scaleL = dy/ mRadius;
// scaleW = dx/ mRadius;
tempRad = tempRad / PI * 180 + 360;
if (tempRad > 360) {
tempRad = tempRad - 360;
}
if (tempRad >= 30 && tempRad < 60) {
mLinearSpeed = -maxLinespeed;
mAugularSpeed = maxWspeed;
} else if (tempRad >= 60 && tempRad < 120) {
mLinearSpeed = -maxLinespeed;
mAugularSpeed = ZERO;
} else if (tempRad >= 120 && tempRad < 150) {
mLinearSpeed = -maxLinespeed;
mAugularSpeed = -maxWspeed;
} else if (tempRad >= 150 && tempRad < 210) {
mLinearSpeed = ZERO;
mAugularSpeed = maxWspeed;
} else if (tempRad >= 210 && tempRad < 240) {
mLinearSpeed = maxLinespeed;
mAugularSpeed = maxWspeed;
} else if (tempRad >= 240 && tempRad < 300) {
mLinearSpeed = maxLinespeed;
mAugularSpeed = ZERO;
} else if (tempRad >= 300 && tempRad < 330) {
mLinearSpeed = maxLinespeed;
mAugularSpeed = -maxWspeed;
} else {
mLinearSpeed = 0;
mAugularSpeed = -maxWspeed;
}
flag = true;
run();
} else {
mAugularSpeed = 0;
mLinearSpeed = 0;
flag = false;
isAlive = false;
}
} else if (event.getAction() == MotionEvent.ACTION_UP) {
if(isLock){
return true;
}
isShowLock = false;
SmallRockerCircleX = mCenterX;
SmallRockerCircleY = mCenterY;
mAugularSpeed = 0;
mLinearSpeed = 0;
flag = false;
isAlive = false;
// moveBean.speed.setLinearSpeed(mLinearSpeed);
// moveBean.speed.setAngularSpeed(mAugularSpeed);
stopCircle();
}
postInvalidateOnAnimation();
return true;
}
2.通过WindowManager 悬浮框 添加锁,解锁
注意使用wmParams.type = WindowManager.LayoutParams.TYPE_APPLICATION
不用添加悬浮框权限
private void initFloatView(){
//获取LayoutParams对象
wmParams = new WindowManager.LayoutParams();
//获取的是LocalWindowManager对象
mWindowManager = ((Activity)getContext()).getWindowManager();
Log.e("TAG", "((Activity)getContext())" + ((Activity)getContext()).getLocalClassName().toString());
//获取的是CompatModeWrapper对象
// mWindowManager = (WindowManager) SkyeeRobotApp.instance.getSystemService(Context.WINDOW_SERVICE);
wmParams.type = WindowManager.LayoutParams.TYPE_APPLICATION;
wmParams.format = PixelFormat.RGBA_8888;;
wmParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
wmParams.gravity = Gravity.LEFT | Gravity.TOP;
wmParams.width = WindowManager.LayoutParams.WRAP_CONTENT;
wmParams.height = WindowManager.LayoutParams.WRAP_CONTENT;
LayoutInflater inflater = ((Activity)getContext()).getLayoutInflater();//LayoutInflater.from(getApplication());
isLockView = (ImageView) inflater.inflate(R.layout.lock_layout, null);
isLockView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
if(isLock){
isLockView.setImageBitmap(unLockBitmap);
isLockView.invalidate();
isShowLock = false;
SmallRockerCircleX = mCenterX;
SmallRockerCircleY = mCenterY;
mAugularSpeed = 0;
mLinearSpeed = 0;
flag = false;
isAlive = false;
CircleView.this.invalidate();
}else {
isLockView.setImageBitmap(lockBitmap);
isLockView.invalidate();
}
isLock = !isLock;
}
});
}
3.示例图
DEMO源码