讓你的應用"飄"起來!Android懸浮窗+自動吸邊效果實戰
作者:Reathin
重要注意事項1. 版本適配:Android 8.0+要用TYPE_APPLICATION_OVERLAY類型。2. 內存管理:記得在onDestroy里移除視圖!3. 用戶體驗:拖動時可以考慮增加半透明效果。4. 權限提示:優雅地引導用戶開啟權限
先搞張"通行證"(權限篇)
在AndroidManifest里掛個牌子
<!-- 告訴系統:我要開懸浮窗啦! -->
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
這就像在游樂園門口掛了個"VIP通道"的牌子~
向用戶申請"特別通行證"
// 檢查是不是Android 6.0以上的"高級游樂園"
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
// 看看通行證有沒有過期
if (!Settings.canDrawOverlays(this)) {
// 申請權限
Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
Uri.parse("package:" + getPackageName()));
startActivityForResult(intent, 1001);
} else {
showFloatingWindow(); // 亮出我們的懸浮窗!
}
}
圖片
創建會"跑"的懸浮窗(核心實現)
懸浮窗基礎配置
// 窗口管家(WindowManager)登場
windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
// 給懸浮窗穿件"衣服"
ImageView floatView = new ImageView(this);
floatView.setImageResource(R.drawable.ic_float);
// 懸浮窗的"身份證信息"
WindowManager.LayoutParams params = new WindowManager.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT,
Build.VERSION.SDK_INT >= Build.VERSION_CODES.O ?
WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY : // Android 8.0+用這個
WindowManager.LayoutParams.TYPE_PHONE, // 老版本用這個
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, // 別搶焦點,做個安靜的美窗
PixelFormat.TRANSLUCENT // 半透明效果更高級
);
// 初始位置:屏幕左上角+向下偏移100像素
params.gravity = Gravity.START | Gravity.TOP;
params.x = 0;
params.y = 100;
// 把懸浮窗"放"到屏幕上
windowManager.addView(floatView, params);
圖片
讓懸浮窗"動"起來
floatView.setOnTouchListener(new View.OnTouchListener() {
private int startX, startY;
private float touchX, touchY;
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN: // 手指按下
startX = params.x;
startY = params.y;
touchX = event.getRawX(); // 記錄觸點X
touchY = event.getRawY(); // 記錄觸點Y
return true;
case MotionEvent.ACTION_MOVE: // 手指滑動
// 計算新位置
params.x = startX + (int)(event.getRawX() - touchX);
params.y = startY + (int)(event.getRawY() - touchY);
windowManager.updateViewLayout(floatView, params);
return true;
case MotionEvent.ACTION_UP: // 手指松開
autoAttachToEdge(); // 觸發吸邊效果
return true;
}
return false;
}
});
磁吸邊效果實現(魔法時刻)
private void autoAttachToEdge() {
int screenWidth = getResources().getDisplayMetrics().widthPixels;
int viewCenterX = params.x + floatView.getWidth()/2;
// 判斷離哪邊近
if(viewCenterX < screenWidth/2) {
params.x = 0; // 吸到左邊緣
} else {
params.x = screenWidth - floatView.getWidth(); // 吸到右邊緣
}
// 添加彈性動畫
ValueAnimator animator = ValueAnimator.ofInt(params.x, targetX);
animator.addUpdateListener(animation -> {
params.x = (int) animation.getAnimatedValue();
windowManager.updateViewLayout(floatView, params);
});
animator.setDuration(300).start();
}
圖片
重要注意事項
1. 版本適配:Android 8.0+要用TYPE_APPLICATION_OVERLAY
類型
2. 內存管理:記得在onDestroy
里移除視圖!
3. 用戶體驗:拖動時可以考慮增加半透明效果
4. 權限提示:優雅地引導用戶開啟權限
快來打造屬于你的"桌面小精靈"吧!代碼在手,創意我有,讓你的應用瞬間擁有靈魂~ ??
源碼:https://github.com/Reathin/Sample-Android/tree/master/module_float
責任編輯:武曉燕
來源:
沐雨花飛碟