日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

android 悬浮球简书,轻松自制flyme悬浮球

發(fā)布時(shí)間:2023/12/15 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 android 悬浮球简书,轻松自制flyme悬浮球 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

前言

去年用了一整年的MX4Pro,魅族留給我最大的印象就是懸浮球了(質(zhì)量問題我就不說了),左右滑動(dòng)切換應(yīng)用、上拉返回桌面、下拉打開通知欄、輕觸返回...,一切都那么絲滑。然而自從上半年換成了s7dege,我感覺怎么也習(xí)慣不了沒有懸浮球的生活了。

三星自己也有一個(gè)類似于懸浮球的功能,不過太過復(fù)雜,不易用,懸浮球本來就該是一個(gè)一步操作的產(chǎn)品,看來三星在軟件設(shè)計(jì)方面還是任重而道遠(yuǎn)。于是乎我便在各大應(yīng)用市場上找懸浮球,把所有排名靠前的懸浮球應(yīng)用都安裝試了一下,最后終于讓我找到了一款幾乎和flyme懸浮球相仿的app。

這款app在我手機(jī)里呆了好幾個(gè)月,是我手機(jī)里除了微信之外,唯一允許自啟動(dòng)的應(yīng)用了。很感謝這款app的開發(fā)者,不僅沒有任何廣告,還非常好用,完美移植了flyme自帶的懸浮球功能。

然而漸漸的,我便感覺到了一絲不舒服,那就是我每次安裝了一個(gè)新app,打開后提示要賦予權(quán)限(存儲(chǔ)、拍照)的時(shí)候,6.0的系統(tǒng)總會(huì)溫馨的彈出一個(gè)框:

然后我就必須到設(shè)置頁面,花半天找到懸浮球,關(guān)掉它的“可出現(xiàn)在頂部的應(yīng)用程”權(quán)限,然后才能回到app,授予權(quán)限。最后,我還得再次跑到設(shè)置頁面,再花半天找到懸浮球,打開它的“可出現(xiàn)在頂部的應(yīng)用程”權(quán)限。朋友啊朋友,這種體驗(yàn),一次就夠了,然而硬是讓我體驗(yàn)了N次啊!

然而有什么能難得倒程序員的呢?剛好這個(gè)周末在家無事,我決定按照自己的習(xí)慣,打造一個(gè)心目中最易用的懸浮球。

設(shè)計(jì)

1.UI

UI很簡單,直接用sketch切了三個(gè)圓,一個(gè)是作為背景的灰色半透明的圓,一個(gè)是中心的小圓,另外還有一個(gè)默認(rèn)隱藏的大圓。

2.功能

因?yàn)樽约旱牟僮髁?xí)慣是固定的,所以也就不需要給懸浮球添加自定義操作的功能了,直接將操作對(duì)應(yīng)的功能寫死即可。

(1)單擊:返回

(2)長按:移動(dòng)懸浮球

(3)左滑右滑:打開最近應(yīng)用程序

(4)上拉:返回桌面

(5)下拉:

這塊我最先開始定義的很簡單,就是下拉通知欄,但是經(jīng)過一天的使用,我又給它加了一個(gè)功能,就是保持下拉狀態(tài)1.5秒,將移除懸浮球。這樣你便可以很簡單的移除掉懸浮球了。

實(shí)現(xiàn)

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

這里首先要感謝郭霖大神的 《 Android桌面懸浮窗效果實(shí)現(xiàn),仿360手機(jī)衛(wèi)士懸浮窗效果》,這部分我參考了這篇文章,成功的將懸浮球添加到了桌面。

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.手勢(shì)判斷

這是最重要的部分了,承擔(dān)著懸浮球的主要功能。

(1)手指按下時(shí)

按下時(shí),隱藏小球,展現(xiàn)大球,并記錄按下位置和按下時(shí)間。

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 (isLongTouch()) {

mIsLongTouch = true;

mVibrator.vibrate(mPattern, -1);

}

}

}, LONG_CLICK_LIMIT);

break;

代碼最后的postDealy時(shí)干嘛使的呢?就是通過延遲300毫秒,判斷是否是長按模式。如果目前還沒有處于其他模式,則可判斷為長按,并震動(dòng)提醒。

(2)手指移動(dòng)時(shí)

這時(shí)要判斷是否是處于長按狀態(tài),如果是,那么進(jìn)入MOVE模式,移動(dòng)懸浮球,如果不是,則判斷操作手勢(shì),即下拉還是上拉等其他手勢(shì)。

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;

進(jìn)行手勢(shì)操作的代碼如下,主要是根據(jù)當(dāng)前坐標(biāo)與按下時(shí)記錄的坐標(biāo)進(jìn)行計(jì)算,判斷手勢(shì),并更新大球位置。

private void doGesture(MotionEvent event) {

float offsetX = event.getX() - mLastDownX;

float offsetY = event.getY() - mLastDownY;

if (Math.abs(offsetX) < mTouchSlop && Math.abs(offsetY) < mTouchSlop) {

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);

//如果長時(shí)間保持下拉狀態(tài),將會(huì)觸發(fā)移除懸浮球功能

postDelayed(new Runnable() {

@Override

public void run() {

if (mCurrentMode == MODE_DOWN && mIsTouching) {

toRemove();

mCurrentMode = MODE_GONE;

}

}

}, REMOVE_LIMIT);

} else {

if (mCurrentMode == MODE_UP) {

return;

}

mCurrentMode = MODE_UP;

mImgBigBall.setX(mBigBallX);

mImgBigBall.setY(mBigBallY - OFFSET);

}

}

}

(3)手指抬起時(shí)

手指抬起后,先要判斷是否是長按模式,不是的話再判斷是否是單擊,都不是的話就根據(jù)當(dāng)前狀態(tài)觸發(fā)對(duì)應(yīng)功能。

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;

效果

到目前為止,懸浮球的功能就實(shí)現(xiàn)了,來看看使用效果如何。

最后再說兩句

花了大半天,總算是大功告成了,程序員,最大的好處就是自己可以定制應(yīng)用😂,

star是最好不過了😬。

魅族小米請(qǐng)注意!試了魅族pro5,先點(diǎn)擊start->進(jìn)入輔助功能界面->點(diǎn)擊無障礙->開啟FloatBall輔助功能。接著還要干一件事,就是魅族自己給懸浮窗加了權(quán)限,必須進(jìn)入設(shè)置->應(yīng)用管理->已安裝中找到floatball->權(quán)限管理->開啟懸浮窗權(quán)限,小米應(yīng)該也是。此處不想吐槽國產(chǎn)ROM

總結(jié)

以上是生活随笔為你收集整理的android 悬浮球简书,轻松自制flyme悬浮球的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。