赞
踩
android实现悬浮球功能:
设置悬浮球View操作代码:
- package lwnewoa.zjsos.com.floadballdemo;
-
- import android.content.Context;
- import android.graphics.Color;
- import android.graphics.PixelFormat;
- import android.os.Build;
- import android.view.Gravity;
- import android.view.LayoutInflater;
- import android.view.MotionEvent;
- import android.view.View;
- import android.view.WindowManager;
-
- /**
- * Author:Stephen
- * Blog: https://me.csdn.net/jifenglie
- * Date:2020/3/16
- * Description:
- */
-
- public class FloatBallView {
-
-
- private Context context;
-
- private int height = 0;
-
- private int width = 0;
-
- public static FloatBallView floatView2;
-
-
- public static FloatBallView getInstance(Context context) {
- if (floatView2 == null) {
- floatView2 = new FloatBallView(context);
- }
- return floatView2;
- }
-
- public FloatBallView(Context c) {
-
- this.context = c;
-
- }
-
- private WindowManager wm;
-
- private View view;// 浮动按钮
-
- WindowManager.LayoutParams params;
-
- /**
- * 添加悬浮View
- *
- * @param
- */
-
- public void createFloatView() {
-
- if (view == null) {
- view = LayoutInflater.from(context).inflate(R.layout.home_floatview, null);
- }
-
-
- wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
- height = wm.getDefaultDisplay().getHeight();
- width = wm.getDefaultDisplay().getWidth();
-
- params = new WindowManager.LayoutParams();
- params.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;// 所有程序窗口的“基地”窗口,其他应用程序窗口都显示在它上面。
- params.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
- params.format = PixelFormat.TRANSLUCENT;// 不设置这个弹出框的透明遮罩显示为黑色
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
- params.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
- } else {
- params.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;
- }
-
- params.width = WindowManager.LayoutParams.WRAP_CONTENT;
- params.height = WindowManager.LayoutParams.WRAP_CONTENT;
- params.gravity = Gravity.TOP | Gravity.LEFT;
- int screenWidth = context.getResources().getDisplayMetrics().widthPixels;
- int screenHeight = context.getResources().getDisplayMetrics().heightPixels;
- params.y = screenHeight - height / 3;//设置距离底部高度为屏幕三分之一
- params.x = screenWidth;
- view.setBackgroundColor(Color.TRANSPARENT);
- view.setVisibility(View.VISIBLE);
- view.setOnTouchListener(new View.OnTouchListener() {
- // 触屏监听
- float lastX, lastY;
- int oldOffsetX, oldOffsetY;
- int tag = 0;// 悬浮球 所需成员变量
-
- @Override
-
- public boolean onTouch(View v, MotionEvent event) {
- final int action = event.getAction();
- float x = event.getX();
- float y = event.getY();
- if (tag == 0) {
- oldOffsetX = params.x; // 偏移量
- oldOffsetY = params.y; // 偏移量
- }
-
- if (action == MotionEvent.ACTION_DOWN) {
- lastX = x;
- lastY = y;
- } else if (action == MotionEvent.ACTION_MOVE) {
- params.x += (int) (x - lastX) / 3; // 减小偏移量,防止过度抖动
- params.y += (int) (y - lastY) / 3; // 减小偏移量,防止过度抖动
- tag = 1;
- wm.updateViewLayout(view, params);
- } else if (action == MotionEvent.ACTION_UP) {
- int newOffsetX = params.x;
- int newOffsetY = params.y;
- // 只要按钮一动位置不是很大,就认为是点击事件
- if (Math.abs(oldOffsetX - newOffsetX) <= 20
- && Math.abs(oldOffsetY - newOffsetY) <= 20) {
- if (l != null) {
- l.onClick(view);
- }
- } else {
- if (params.x < width / 2) {
- params.x = 0;
- } else {
- params.x = width;
- }
- wm.updateViewLayout(view, params);
- tag = 0;
- }
- }
- return true;
- }
- });
- try {
- wm.addView(view, params);
- } catch (Exception e) {
-
- }
-
- /*floatView2.onFloatViewClick(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- //这边是点击悬浮按钮的响应事件
- Toast.makeText(context, "点击了悬浮球", Toast.LENGTH_LONG);
- }
- });*/
- }
-
- /**
- * 点击浮动按钮触发事件,需要override该方法
- */
-
- private View.OnClickListener l;
-
- public void onFloatViewClick(View.OnClickListener l) {
- this.l = l;
- }
-
- /**
- * 将悬浮View从WindowManager中移除,需要与createFloatView()成对出现
- */
-
- public void removeFloatView() {
- if (wm != null && view != null) {
- wm.removeViewImmediate(view);
- // wm.removeView(view);//不要调用这个,WindowLeaked
- view = null;
- wm = null;
- }
- }
-
- /**
- * 隐藏悬浮View
- */
-
- public void hideFloatView() {
- if (wm != null && view != null && view.isShown()) {
- view.setVisibility(View.GONE);
- }
- }
-
- /**
- * 显示悬浮View
- */
-
- public void showFloatView() {
- if (wm != null && view != null && !view.isShown()) {
- view.setVisibility(View.VISIBLE);
- }
- }
-
- public void updateViewLayout() {
- if (wm != null) {
- int screenWidth = (int) 480;
- int screenHeight = (int) 720;
- if (screenWidth == 0) {
- screenWidth = context.getResources().getDisplayMetrics().widthPixels;
- }
-
- if (screenHeight == 0) {
- screenHeight = context.getResources().getDisplayMetrics().heightPixels;
- params.y = screenHeight - height / 3;//设置距离底部高度为屏幕三分之一
- } else {
- params.y = screenHeight;
- }
- params.x = screenWidth;
- wm.updateViewLayout(view, params);
- }
-
- }
-
- }
-
home_floatview.xml :
- <?xml version="1.0" encoding="utf-8"?>
- <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent">
-
-
- <de.hdodenhof.circleimageview.CircleImageView
- android:layout_width="96dp"
- android:layout_height="96dp"
- android:src="@drawable/ic_home_zfxzs" />
-
- </android.support.constraint.ConstraintLayout>
项目首页使用:
- package lwnewoa.zjsos.com.floadballdemo;
-
- import android.content.Intent;
- import android.net.Uri;
- import android.os.Build;
- import android.os.Bundle;
- import android.provider.Settings;
- import android.support.v7.app.AppCompatActivity;
- import android.view.View;
- import android.widget.Button;
- import android.widget.Toast;
-
- public class MainActivity extends AppCompatActivity {
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
-
-
- Button button1 = findViewById(R.id.button1);
- Button button2 = findViewById(R.id.button2);
-
- button1.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
- //检查是否已经授予权限
- if (!Settings.canDrawOverlays(MainActivity.this)) {
- //若未授权则请求权限
- Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION);
- intent.setData(Uri.parse("package:" + getPackageName()));
- startActivityForResult(intent, 0);
- }
- }
- }
- });
-
- button2.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- FloatBallView.getInstance(MainActivity.this).createFloatView();
-
- }
- });
-
- //这边是点击悬浮按钮的响应事件
-
- FloatBallView.getInstance(MainActivity.this).onFloatViewClick(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- Toast.makeText(MainActivity.this, "点击了悬浮球", Toast.LENGTH_LONG).show();
- }
- });
-
-
- }
- }
activity_main :
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical"
- tools:context="lwnewoa.zjsos.com.floadballdemo.MainActivity">
-
- <Button
- android:id="@+id/button1"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginLeft="30dp"
- android:layout_marginTop="50dp"
- android:text="获取悬浮球权限" />
-
-
- <Button
- android:id="@+id/button2"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginLeft="30dp"
- android:layout_marginTop="10dp"
- android:text="打开悬浮球" />
-
- </LinearLayout>
权限:
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
第三方 圆形图片
implementation 'de.hdodenhof:circleimageview:2.1.0'
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。