Android 实现无需权限的悬浮球效果,可适配至Android 10

本文介绍了一种无需特殊权限即可使用的悬浮窗实现方法,包括自动贴边、红点提示等功能,并提供了详细的代码示例。

前言:

最近闲来无事,突然想起搞一下悬浮球,之前的项目的悬浮球一直都需要授权,android6.0以后需要手动授权,悬浮球使用时就非常不便,这里为大家带来一种无需权限的悬浮球实现方式。

  • 无需权限!
  • 无需权限!

功能:

  • 自动贴边
  • 显示红点
  • 隐藏红点
  • 自由移动
  • 显示悬浮球
  • 隐藏悬浮球
  • 销毁悬浮球
  • 接入简单,可进行自定义拓展

附上demo地址

效果如下:

在这里插入图片描述

以下是主要的代码部分:

MainActivity.class

public class MainActivity extends Activity {
   
   

    @Override
    protected void onCreate(Bundle savedInstanceState) {
   
   
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        findViewById(R.id.showbtn).setOnClickListener(new View.OnClickListener() {
   
   
            @Override
            public void onClick(View view) {
   
   
                RoundView.getInstance().showRoundView(MainActivity.this);

            }
        });

        findViewById(R.id.hidebtn).setOnClickListener(new View.OnClickListener() {
   
   
            @Override
            public void onClick(View view) {
   
   
                RoundView.getInstance().hideRoundView(MainActivity.this);
            }
        });

        findViewById(R.id.closebtn).setOnClickListener(new View.OnClickListener() {
   
   
            @Override
            public void onClick(View view) {
   
   
                RoundView.getInstance().closeRoundView(MainActivity.this);
            }
        });

        findViewById(R.id.showMsgbtn).setOnClickListener(new View.OnClickListener() {
   
   
            @Override
            public void onClick(View view) {
   
   
                RoundView.getInstance().showRoundMsg();
            }
        });
        findViewById(R.id.hideMsgbtn).setOnClickListener(new View.OnClickListener() {
   
   
            @Override
            public void onClick(View view) {
   
   
                RoundView.getInstance().hideRoundMsg();
            }
        });
        findViewById(R.id.exitbtn).setOnClickListener(new View.OnClickListener() {
   
   
            @Override
            public void onClick(View view) {
   
   
                android.os.Process.killProcess(android.os.Process.myPid());
            }
        });
    }
}

RoundView.class

/**
 * 悬浮窗管理器
 */
public class RoundView {
   
   

    private static RoundView sFloatingLayer;

    /**
     * 用于控制在屏幕上添加或移除悬浮窗
     */
    private static WindowManager mWindowManager;

    public static boolean isNearLeft = true;  //判断悬浮球是否在左边

    private static boolean isShow = false;  //判断悬浮球是否已经显示

    private int mWidth,mHeight;   //屏幕的宽高

    public static final int WIN_NONE = 0;// 不展示
    public static final int WIN_SMALL = 1;// 小浮标
    public static final int WIN_BIG = 2;// 展开
    public static final int WIN_HIDE = 3;// 靠边隐藏 无操作隐藏
    public static int winStatus;

    public static boolean isMsg=false;  //红点消息提示是否显示


    /**
     * 小悬浮窗view的实例
     */
    private static RoundWindowSmallView smallWindow;


    /**
     * 隐藏悬浮窗view的实例
     */
    private static RoundWindowHideView hideWindow;

    /**
     * 大悬浮窗view的实例
     */
    private static RoundWindowBigView bigWindow;


    /**
     * 大小悬浮窗view的参数
     */
    private static WindowManager.LayoutParams mLayoutParams;


    public static RoundView getInstance() {
   
   
        if (null == sFloatingLayer) {
   
   
            synchronized (RoundView.class) {
   
   
                if (null == sFloatingLayer) {
   
   
                    sFloatingLayer = new RoundView();
                }
            }
        }
        return sFloatingLayer;
    }

    /**
     * 显示悬浮窗
     * @param context
     */
    public void showRoundView(Context context) {
   
   
        if(mWindowManager==null){
   
   
            mWindowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        }

        //每一次显示浮窗前都重新获取一次宽高,避免横竖屏切换后宽高变化
        getWidthAndHeight(context);

        if(!isShow){
   
   
            //处于非显示状态,可以显示
            isShow=true;
            if(winStatus==WIN_NONE){
   
   
                //处于未创建状态,请创建
                showSmallwin(context);
            }else {
   
   
                //已创建了,直接显示
                switch (winStatus){
   
   
                    case WIN_SMALL:
                        if(smallWindow!=null)
                            smallWindow.setVisibilityState(View.VISIBLE);
                        break;
                    case WIN_BIG:
                        if(bigWindow!=null)
                            bigWindow.setVisibilityState(View.VISIBLE);
                        break;
                    case WIN_HIDE:
                        if(hideWindow!=null)
                            hideWindow.setVisibilityState(View.VISIBLE);
                        break;
                }
            }
        }
    }

    /**
     * 隐藏悬浮窗
     * @param context
     */
    public void hideRoundView(Context context) {
   
   
        if(isShow){
   
   
            //处于显示状态,可以隐藏
            isShow=false;
            switch (winStatus){
   
   
                case WIN_SMALL:
                    if(smallWindow!=null)
                    smallWindow.setVisibilityState(View.GONE);
                    break;
                case WIN_BIG:
                    if(bigWindow!=null)
                    bigWindow.setVisibilityState(View.GONE);
                    break;
                case WIN_HIDE:
                    if(hideWindow!=null)
                    hideWindow.setVisibilityState(View.GONE);
                    break;
            }
        }
    }

    /**
     * 销毁悬浮窗
     * @param context
     */
    public void closeRoundView(Context context) {
   
   
        isShow=false;
        isMsg=false;
        winStatus=WIN_NONE;
        removeSmallWindow(context);
        removeBigWindow
评论 6
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值