Android弹出悬浮窗引导用户开启应用设置

由于国产手机修改了android原生系统很多设置,在这些手机上运行app可能要做一些国产化的设置,最开始是在一个页面里做的,写得很详细,第一步要进入到设置,然后应用管理,选择应用,然后选择权限等等,可能用户都记不清楚了。下面改用弹出窗口的形式,可以在操作的时候看窗口中的提示,提供更好的用户体验。
效果如下:
这里写图片描述
感谢在线gif生成网址 https://ezgif.com/video-to-gif 真的很好用
在Demo中有两个button,一个是用来打开悬浮窗权限的,一个是显示悬浮窗并跳转到其它页面的,看看代码大致结构:
这里写图片描述

第一个按钮跳转到开启悬浮窗页面后,在Mate9上无法选中,我也不知道怎么回事,在Mate10和P10上就没有这个问题。但在Mate9上,可以直接打开悬浮窗,而在Mate10和P10上会提示说没有开启悬浮窗权限。
通过WindowManager实现悬浮窗口的创建、更新和移除,下面是WindowManager的三个方法:
这里写图片描述
addView传入的view是通过LayoutInflater.from(this).inflate(R.layout.activity_dialog, null)生成的,R.layout.activity_dialog代码如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:background="@color/blue"
    android:layout_width="match_parent"
    android:layout_height="100dp">

    <LinearLayout
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="7"
        android:orientation="vertical"
        android:layout_marginLeft="15dp">
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="40dp"
            android:textSize="15dp"
            android:layout_marginTop="10dp"
            android:textColor="@color/white"
            android:text="权限设置引导"/>
        <TextView
            android:id="@+id/permission_tip"
            android:layout_width="wrap_content"
            android:layout_height="60dp"
            android:textColor="@color/white"
            android:text="打开相应开关"
            android:textSize="15dp"/>
    </LinearLayout>
    <LinearLayout
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:gravity="top|right"
        android:layout_marginRight="6dp"
        android:layout_marginTop="9dp">
        <ImageView
            android:id="@+id/dialog_cancel"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@drawable/permission_del"/>
    </LinearLayout>

</LinearLayout>

下面是弹出悬浮窗的代码:

public void showDialog(){
        localLayoutParams = new WindowManager.LayoutParams();
        mWm= (WindowManager)getSystemService(Context.WINDOW_SERVICE);
        DisplayMetrics localDisplayMetrics = new DisplayMetrics();
        mWm.getDefaultDisplay().getMetrics(localDisplayMetrics);
        int i1 = localDisplayMetrics.widthPixels;
        localLayoutParams.type = WindowManager.LayoutParams.TYPE_TOAST;
        if(Build.VERSION.SDK_INT > 24) {
            localLayoutParams.type = WindowManager.LayoutParams.TYPE_PHONE;
        }
        localLayoutParams.format = 1;
        localLayoutParams.flags = 40;
        localLayoutParams.gravity = 81;
        localLayoutParams.x = 0;
        localLayoutParams.y = 60;
        localLayoutParams.width = (i1 - 90);
        localLayoutParams.height = -2;
        a = ((LinearLayout) LayoutInflater.from(this).inflate(R.layout.activity_dialog, null));
        mWm.addView(a, localLayoutParams);
        ((TextView)a.findViewById(R.id.permission_tip)).setText("弹出窗口");
        ImageView mDialogCancel = a.findViewById(R.id.dialog_cancel);
        mDialogCancel.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                removeDialog();
            }
        });
        a.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                switch (event.getAction()) {
                    case MotionEvent.ACTION_DOWN:
                        mStartY = event.getRawY();
                        Log.i(CLASS_TAG, "ACTION_DOWN,mStartY:" + mStartY);
                        Log.i(CLASS_TAG, "localLayoutParams.y:" + localLayoutParams.y);
                        mDownTime = System.currentTimeMillis();
                        break;
                    case MotionEvent.ACTION_MOVE:
                        Log.i(CLASS_TAG, "ACTION_MOVE,event.getRawY():" + event.getRawY());
                        localLayoutParams.y += mStartY-event.getRawY();
                        Log.i(CLASS_TAG, "localLayoutParams.y:" + localLayoutParams.y);
                        mWm.updateViewLayout(a, localLayoutParams);
                        mStartY = event.getRawY();
                        break;
                    case MotionEvent.ACTION_UP:
                        mUpTime = System.currentTimeMillis();
                        return mUpTime-mDownTime>200;
                }
                return false;
            }
        });
    }

按下的时候记录纵坐标位置,move的时候再记录位置,计算改变量,修改布局参数,并通过windowmanager的updateViewLayout更新窗口位置;抬起和按下时间相差大于200ms,则消费掉点击时间,认为是一次拖动操作;否则返回true,执行点击事件。

完整代码已上传gitbug:https://github.com/acxingyun/FloatingDialog.git

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值