由于国产手机修改了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