在Android中實(shí)現(xiàn)浮窗并添加吸邊效果的代碼示例
1. 添加權(quán)限
首先,確保您的應(yīng)用具有顯示懸浮窗的權(quán)限。在 AndroidManifest.xml 文件中添加以下權(quán)限:
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
2. 請求懸浮窗權(quán)限
在 Android 6.0(API 級別 23)及更高版本中,您需要在運(yùn)行時請求懸浮窗權(quán)限:
import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.provider.Settings;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
public class MainActivity extends AppCompatActivity {
private static final int REQUEST_CODE_OVERLAY_PERMISSION = 1001;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
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, REQUEST_CODE_OVERLAY_PERMISSION);
} else {
// 已獲得權(quán)限,顯示浮窗
showFloatingWindow();
}
} else {
// 低于 Android 6.0,直接顯示浮窗
showFloatingWindow();
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_CODE_OVERLAY_PERMISSION) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (Settings.canDrawOverlays(this)) {
// 已獲得權(quán)限,顯示浮窗
showFloatingWindow();
}
}
}
}
private void showFloatingWindow() {
// 顯示浮窗的代碼
}
}
3. 創(chuàng)建浮窗并實(shí)現(xiàn)吸邊效果
以下是一個完整的示例,展示如何創(chuàng)建一個浮窗并實(shí)現(xiàn)吸邊效果:
import android.content.Context;
import android.graphics.PixelFormat;
import android.os.Build;
import android.os.Bundle;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;
import android.widget.ImageView;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
public class MainActivity extends AppCompatActivity {
private WindowManager windowManager;
private WindowManager.LayoutParams layoutParams;
private ImageView floatingView;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
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();
}
} else {
showFloatingWindow();
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == 1001) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (Settings.canDrawOverlays(this)) {
showFloatingWindow();
}
}
}
}
private void showFloatingWindow() {
windowManager = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
floatingView = new ImageView(this);
floatingView.setImageResource(R.drawable.ic_launcher_foreground); // 替換為您的圖標(biāo)
layoutParams = new WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT,
Build.VERSION.SDK_INT >= Build.VERSION_CODES.O ?
WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY :
WindowManager.LayoutParams.TYPE_PHONE,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.TRANSLUCENT
);
layoutParams.gravity = Gravity.TOP | Gravity.LEFT;
layoutParams.x = 0;
layoutParams.y = 100;
windowManager.addView(floatingView, layoutParams);
floatingView.setOnTouchListener(new View.OnTouchListener() {
private int initialX;
private int initialY;
private float initialTouchX;
private float initialTouchY;
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
initialX = layoutParams.x;
initialY = layoutParams.y;
initialTouchX = event.getRawX();
initialTouchY = event.getRawY();
return true;
case MotionEvent.ACTION_MOVE:
layoutParams.x = initialX + (int) (event.getRawX() - initialTouchX);
layoutParams.y = initialY + (int) (event.getRawY() - initialTouchY);
windowManager.updateViewLayout(floatingView, layoutParams);
return true;
case MotionEvent.ACTION_UP:
int screenWidth = getResources().getDisplayMetrics().widthPixels;
if (layoutParams.x < screenWidth / 2) {
layoutParams.x = 0;
} else {
layoutParams.x = screenWidth;
}
windowManager.updateViewLayout(floatingView, layoutParams);
return true;
}
return false;
}
});
}
@Override
protected void onDestroy() {
super.onDestroy();
if (floatingView != null) {
windowManager.removeView(floatingView);
}
}
}
解釋
- 請求懸浮窗權(quán)限:在
onCreate方法中檢查并請求懸浮窗權(quán)限。 - 創(chuàng)建浮窗:使用
WindowManager創(chuàng)建浮窗,并設(shè)置WindowManager.LayoutParams。 - 實(shí)現(xiàn)吸邊效果:通過
setOnTouchListener方法監(jiān)聽浮窗的觸摸事件,在ACTION_UP事件中實(shí)現(xiàn)吸邊效果。
注意事項(xiàng)
- 權(quán)限管理:確保在 Android 6.0 及更高版本中正確請求懸浮窗權(quán)限。
- 懸浮窗類型:在 Android 8.0 及更高版本中,使用
WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY類型。 - 資源管理:在
onDestroy方法中移除浮窗視圖,避免內(nèi)存泄漏。
到此這篇關(guān)于在Android中實(shí)現(xiàn)浮窗并添加吸邊效果的文章就介紹到這了,更多相關(guān)Android實(shí)現(xiàn)浮窗并添加吸邊內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Android開發(fā)之5.0activity跳轉(zhuǎn)時共享元素的使用方法
下面小編就為大家分享一篇Android開發(fā)之5.0activity跳轉(zhuǎn)時共享元素的使用方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-01-01
Android Studio報:“Attribute application@theme or @ icon ”問題的解
這篇文章主要給大家介紹了關(guān)于Android Studio報:“Attribute application@theme or @ icon ”問題的解決方法,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考借鑒,下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。2017-12-12
Android實(shí)現(xiàn)viewpager實(shí)現(xiàn)循環(huán)輪播效果
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)viewpager實(shí)現(xiàn)循環(huán)輪播效果,具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-03-03
Android實(shí)現(xiàn)點(diǎn)擊兩次返回鍵退出
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)點(diǎn)擊兩次返回鍵退出的相關(guān)資料,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-01-01
Android開發(fā)之OkHttpUtils的具體使用方法
這篇文章主要介紹了Android開發(fā)之OkHttpUtils的具體使用方法,非常具有實(shí)用價值,需要的朋友可以參考下2017-08-08

