android添加桌面悬浮窗
1. 添加权限
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
2. 自定义悬浮窗控件
@SuppressLint("ViewConstructor") public class OEdOverLayView extends FrameLayout { public static OEdOverLayView create(Context context) { return new OEdOverLayView(context); } public static WindowManager.LayoutParams createLayoutParams() { final WindowManager.LayoutParams params = new WindowManager.LayoutParams(WRAP_CONTENT, WRAP_CONTENT, TYPE_TOAST, FLAG_NOT_FOCUSABLE | FLAG_NOT_TOUCH_MODAL | FLAG_LAYOUT_NO_LIMITS | FLAG_LAYOUT_INSET_DECOR | FLAG_LAYOUT_IN_SCREEN, TRANSLUCENT); params.gravity = Gravity.TOP | Gravity.LEFT; return params; } private OEdOverLayView(@NonNull Context context) { super(context); inflate(context, R.layout.widget_oed_overlay, this); init(); }
3. 加载控件到桌面
private void addOverLayView() { if (oEdOverLayView == null) { oEdOverLayView = OEdOverLayView.create(getApplicationContext()); WindowManager windowManager = (WindowManager) getApplicationContext().getSystemService(WINDOW_SERVICE); windowManager.addView(oEdOverLayView, OEdOverLayView.createLayoutParams()); oEdOverLayView.getRootLayout().setOnTouchListener(new OEdOverLayMoveListener(windowManager, oEdOverLayView)); } }
4. 添加移动事件
public class OEdOverLayMoveListener implements View.OnTouchListener { private final WindowManager windowManager; private final View view; private WindowManager.LayoutParams params; private int initialX; private int initialY; private float initialTouchX; private float initialTouchY; public OEdOverLayMoveListener(WindowManager windowManager, View view) { this.windowManager = windowManager; this.view = view; this.params = (WindowManager.LayoutParams) view.getLayoutParams(); } @Override public boolean onTouch(View v, MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: //remember the initial position. initialX = params.x; initialY = params.y; //get the touch location initialTouchX = event.getRawX(); initialTouchY = event.getRawY(); return true; case MotionEvent.ACTION_MOVE: //Calculate the X and Y coordinates of the view. params.x = initialX + (int) (event.getRawX() - initialTouchX); params.y = initialY + (int) (event.getRawY() - initialTouchY); //Update the layout with new X & Y coordinate windowManager.updateViewLayout(view, params); return true; } return true; } } // return ture 会消费掉touch事件,导致onclick无法获取事件
5. 小细节
public static WindowManager.LayoutParams createLayoutParams() { final WindowManager.LayoutParams params = new WindowManager.LayoutParams(WRAP_CONTENT, WRAP_CONTENT, TYPE_TOAST, FLAG_NOT_FOCUSABLE | FLAG_NOT_TOUCH_MODAL | FLAG_LAYOUT_NO_LIMITS | FLAG_LAYOUT_INSET_DECOR | FLAG_LAYOUT_IN_SCREEN, TRANSLUCENT); params.gravity = Gravity.TOP | Gravity.LEFT; return params; }
TYPE_TOAST 和 android.permission.SYSTEM_ALERT_WINDOW 可以在用户一旦取消悬浮窗权限时,添加悬浮窗
学会勇敢