android 悬浮球松手动画,轻松自制flyme悬浮球

前言

去年用了一整年的MX4Pro,魅族留给我最大的印象就是悬浮球了(质量问题我就不说了),左右滑动切换应用、上拉返回桌面、下拉打开通知栏、轻触返回…,一切都那么丝滑。然而自从上半年换成了s7dege,我感觉怎么也习惯不了没有悬浮球的生活了。

三星自己也有一个类似于悬浮球的功能,不过太过复杂,不易用,悬浮球本来就该是一个一步操作的产品,看来三星在软件设计方面还是任重而道远。于是乎我便在各大应用市场上找悬浮球,把所有排名靠前的悬浮球应用都安装试了一下,最后终于让我找到了一款几乎和flyme悬浮球相仿的app。

AAffA0nNPuCLAAAAAElFTkSuQmCC

然后我就必须到设置页面,花半天找到悬浮球,关掉它的“可出现在顶部的应用程”权限,然后才能回到app,授予权限。最后,我还得再次跑到设置页面,再花半天找到悬浮球,打开它的“可出现在顶部的应用程”权限。朋友啊朋友,这种体验,一次就够了,然而硬是让我体验了N次啊!

然而有什么能难得倒程序员的呢好这个周末在家无事,我决定按照自己的习惯,打造一个心目中最易用的悬浮球。

设计

1.UI

UI很简单,直接用sketch切了三个圆,一个是作为背景的灰色半透明的圆,一个是中心的小圆,另外还有一个默认隐藏的大圆。

2.功能

因为自己的操作习惯是固定的,所以也就不需要给悬浮球添加自定义操作的功能了,直接将操作对应的功能写死即可。

(1)单击:返回

(2)长按:移动悬浮球

(3)左滑右滑:打开最近应用程序

(4)上拉:返回桌面

(5)下拉:

这块我最先开始定义的很简单,就是下拉通知栏,但是经过一天的使用,我又给它加了一个功能,就是保持下拉状态1.5秒,将移除悬浮球。这样你便可以很简单的移除掉悬浮球了。

实现

1.如何添加悬浮球到桌面

这里首先要感谢郭霖大神的 《 Android桌面悬浮窗效果实现,仿360手机卫士悬浮窗效果》,这部分我参考了这篇文章,成功的将悬浮球添加到了桌面。public static void addBallView(Context context) {

if (mBallView == null) {

WindowManager windowManager = getWindowManager(context);

int screenWidth = windowManager.getDefaultDisplay().getWidth();

int screenHeight = windowManager.getDefaultDisplay().getHeight();

mBallView = new FloatBallView(context);

LayoutParams params = new LayoutParams();

params.x = screenWidth;

params.y = screenHeight / 2;

params.width = WindowManager.LayoutParams.WRAP_CONTENT;

params.height = WindowManager.LayoutParams.WRAP_CONTENT;

params.gravity = Gravity.LEFT | Gravity.TOP;

params.type = LayoutParams.TYPE_PHONE;

params.format = PixelFormat.RGBA_8888;

params.flags = LayoutParams.FLAG_NOT_TOUCH_MODAL

| LayoutParams.FLAG_NOT_FOCUSABLE;

mBallView.setLayoutParams(params);

windowManager.addView(mBallView, params);

}

}

2.手势判断

这是最重要的部分了,承担着悬浮球的主要功能。

(1)手指按下时

按下时,隐藏小球,展现大球,并记录按下位置和按下时间。case MotionEvent.ACTION_DOWN:

mIsTouching = true;

mImgBall.setVisibility(INVISIBLE);

mImgBigBall.setVisibility(VISIBLE);

mLastDownTime = System.currentTimeMillis();

mLastDownX = event.getX();

mLastDownY = event.getY();

postDelayed(new Runnable() {

@Override

public void run() {

if (!mIsLongTouch && mIsTouching && mCurrentMode == MODE_NONE) {

mIsLongTouch = isLongClick(event);

}

}

}, LONG_CLICK_LIMIT);

break;

代码最后的postDealy时干嘛使的呢是通过延迟300毫秒,判断是否是长按模式。其中判断长按的方法代码如下:private boolean isLongClick(MotionEvent event) {

float offsetX = Math.abs(event.getX() – mLastDownX);

float offsetY = Math.abs(event.getY() – mLastDownY);

long time = System.currentTimeMillis() – mLastDownTime;

if (offsetX = LONG_CLICK_LIMIT) {

//震动提醒

mVibrator.vibrate(mPattern, -1);

return true;

} else {

return false;

}

}

(2)手指移动时

这时要判断是否是处于长按状态,如果是,那么进入MOVE模式,移动悬浮球,如果不是,则判断操作手势,即下拉还是上拉等其他手势。case MotionEvent.ACTION_MOVE:

if (!mIsLongTouch && isTouchSlop(event)) {

return true;

}

if (mIsLongTouch && (mCurrentMode == MODE_NONE || mCurrentMode == MODE_MOVE)) {

mLayoutParams.x = (int) (event.getRawX() – mOffsetToParent);

mLayoutParams.y = (int) (event.getRawY() – mOffsetToParentY);

mWindowManager.updateViewLayout(FloatBallView.this, mLayoutParams);

mBigBallX = mImgBigBall.getX();

mBigBallY = mImgBigBall.getY();

mCurrentMode = MODE_MOVE;

} else {

doGesture(event);

}

break;

进行手势操作的代码如下,主要是根据当前坐标与按下时记录的坐标进行计算,判断手势,并更新大球位置。private void doGesture(MotionEvent event) {

float offsetX = event.getX() – mLastDownX;

float offsetY = event.getY() – mLastDownY;

if (Math.abs(offsetX) 

return;

}

if (Math.abs(offsetX) > Math.abs(offsetY)) {

if (offsetX > 0) {

if (mCurrentMode == MODE_RIGHT) {

return;

}

mCurrentMode = MODE_RIGHT;

mImgBigBall.setX(mBigBallX + OFFSET);

mImgBigBall.setY(mBigBallY);

} else {

if (mCurrentMode == MODE_LEFT) {

return;

}

mCurrentMode = MODE_LEFT;

mImgBigBall.setX(mBigBallX – OFFSET);

mImgBigBall.setY(mBigBallY);

}

} else {

if (offsetY > 0) {

if (mCurrentMode == MODE_DOWN || mCurrentMode == MODE_GONE) {

return;

}

mCurrentMode = MODE_DOWN;

mImgBigBall.setX(mBigBallX);

mImgBigBall.setY(mBigBallY + OFFSET);

//如果长时间保持下拉状态,将会触发移除悬浮球功能

postDelayed(new Runnable() {

@Override

public void run() {

if (mCurrentMode == MODE_DOWN && mIsTouching) {

toRemove();

mCurrentMode = MODE_GONE;

}

}

}, TO_APP_INDEX_LIMIT);

} else {

if (mCurrentMode == MODE_UP) {

return;

}

mCurrentMode = MODE_UP;

mImgBigBall.setX(mBigBallX);

mImgBigBall.setY(mBigBallY – OFFSET);

}

}

}

(3)手指抬起时

手指抬起后,先要判断是否是长按模式,不是的话再判断是否是单击,都不是的话就根据当前状态触发对应功能。case MotionEvent.ACTION_CANCEL:

case MotionEvent.ACTION_UP:

mIsTouching = false;

if (mIsLongTouch) {

mIsLongTouch = false;

} else if (isClick(event)) {

AccessibilityUtil.doBack(mService);

} else {

doUp();

}

mImgBall.setVisibility(VISIBLE);

mImgBigBall.setVisibility(INVISIBLE);

mCurrentMode = MODE_NONE;

break;

效果

到目前为止,悬浮球的功能就实现了,来看看使用效果如何。

AAffA0nNPuCLAAAAAElFTkSuQmCC

最后再说两句

花了大半天,总算是大功告成了,程序员,最大的好处就是自己可以定制应用

相关资源:漂浮截图工具-教育工具类资源

来源:SecretCity

声明:本站部分文章及图片转载于互联网,内容版权归原作者所有,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

上一篇 2021年4月23日
下一篇 2021年4月23日

相关推荐