最近开发中遇到的需求,最终通过使用WindowManager实现该功能,可通过继承扩展。

import android.content.Context;import android.graphics.PixelFormat;import android.view.Gravity;import android.view.KeyEvent;import android.view.LayoutInflater;import android.view.View;import android.view.WindowManager;public class FloatingMenu {    public View mView;    Context mContext;    private WindowManager windowManager;    private Boolean isShowing = false;/**     * 这里采用的自定义点击回调事件     */    FloatingMenu(Context context, int resourceID, View.OnClickListener onClickListener) {        mContext = context;        windowManager = (WindowManager) mContext.getApplicationContext().getSystemService(Context.WINDOW_SERVICE);        mView = initView(mContext, resourceID, onClickListener);    }/**     * 显示弹框     */    public void show() {        if (isShowing) {            return;        }        isShowing = true;//检查权限if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {            if (!Settings.canDrawOverlays(mContext)) {                //启动Activity让用户授权                Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION);                ContextUtil.getActivity(mContext).startActivity(intent);                return;            }        }        final WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams();        //检查版本,注意当type为TYPE_APPLICATION_OVERLAY时,铺满活动窗口,但在关键的系统窗口下面,如状态栏或IME        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {            layoutParams.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;        } else {            layoutParams.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;        }        //覆盖状态栏        //layoutParams.flags = WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;        layoutParams.flags = WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;        layoutParams.format = PixelFormat.TRANSLUCENT;        layoutParams.width = WindowManager.LayoutParams.MATCH_PARENT;        layoutParams.height = WindowManager.LayoutParams.MATCH_PARENT;        layoutParams.gravity = Gravity.CENTER;        windowManager.addView(mView, layoutParams);    }    /**     * 隐藏弹框     */    public void dismiss() {        if (isShowing && mView != null) {            windowManager.removeViewImmediate(mView);            isShowing = false;        }    }/**     * 初始化     */    private View initView(Context context, int resourceID, View.OnClickListener onClickListener) {        final View view = LayoutInflater.from(context).inflate(resourceID, null);        //设置点击事件        view.setOnClickListener(onClickListener);        //监听BACK按键        view.setOnKeyListener(new View.OnKeyListener() {            @Override            public boolean onKey(View v, int keyCode, KeyEvent event) {                if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) {                    dismiss();                    return true;                }                return false;            }        });        //监听BACK按键时必须使得相应的View获取焦点(使用post方式取得焦点),否则setOnKeyListener的onKey方法永远不会被回调,按键就监听不到!        view.post(new Runnable() {            @Override            public void run() {                view.setFocusable(true);                view.setFocusableInTouchMode(true);                view.requestFocus();            }        });        return view;    }}

附:

/** * 得到 Context 对应的 Activity。 */public static Activity getActivity(Context context) {return context instanceof Activity ? (Activity) context : null;}

更多相关文章

  1. Android交互体验必知:功能按键事件
  2. android 触摸(Touch)事件、点击(Click)事件的区别(详细解析)
  3. Android事件分发机制 详解攻略,您值得拥有
  4. Android - Android Studio 的 Preview窗口
  5. android ListView中添加ImageButton按钮并绑定事件
  6. android:imeOptions 控制软键盘右下角按键

随机推荐

  1. android ndk 使用第三方静态库
  2. No IDEA annotations attached to the JD
  3. android中Message机制的灵活应用
  4. android开发积累4-android使用HttpURLCon
  5. Android类库介绍
  6. Android(安卓)模拟器(emulator)无法启动A
  7. android点滴(15)--ubuntu下配置Android(
  8. Android布局容器
  9. Android系统信息与安全机制
  10. Android之EditText指定类型数据