WindowManager添加一个悬浮的Window

最近有这样一个需求,直接看App:


点击按钮可以让Activity进入后台(注意:不是finish),然后自己可以在手机上做其他事情,在点击按钮,就可以返回。

这个主要的逻辑就是在Appliction中加载这个按钮的布局,然后添加到WindowManager中,直接看代码:

public class MyApplication extends Application
        implements View.OnClickListener {
    private boolean isMainShow = true;
    private MainActivity mActivity;

    @Override
    public void onCreate() {
        super.onCreate();
        createFloatWindow();
    }

    public void createFloatWindow() {
        LayoutInflater inflater = LayoutInflater.from(this);
        View view = inflater.inflate(R.layout.float_window, null);
        ImageView ivFloat = (ImageView) view.findViewById(R.id.iv_float);
        ivFloat.setOnClickListener(this);
        //获取 WindowManager对象
        WindowManager windowManager =
                (WindowManager) getSystemService(Context.WINDOW_SERVICE);
        //获取 LayoutParams
        WindowManager.LayoutParams windowManagerParams =
                new WindowManager.LayoutParams();
        //type参数表示window的类型
        windowManagerParams.type =
                android.view.WindowManager.LayoutParams.TYPE_PHONE;
        // 设置图片格式,效果为背景透明
        windowManagerParams.format = PixelFormat.RGBA_8888;
        //flags表示window的属性
        windowManagerParams.flags =
                android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
                        | android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
        //设置Gravity
        windowManagerParams.gravity = Gravity.RIGHT | Gravity.TOP;
        // 以屏幕左上角为原点,设置xy初始值
        windowManagerParams.x = 0;
        windowManagerParams.y = 0;
        // 设置悬浮窗口长宽数据
        windowManagerParams.width = LinearLayout.LayoutParams.WRAP_CONTENT;
        windowManagerParams.height = LinearLayout.LayoutParams.WRAP_CONTENT;
        // 显示FloatView图像
        windowManager.addView(view, windowManagerParams);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.iv_float:
                if (isMainShow) {
                    mActivity.moveTaskToBack(true);
                    isMainShow = false;
                } else {
                    Intent intent = new Intent();
                    intent.setClass(getApplicationContext(),
                            MainActivity.class);
                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                    startActivity(intent);
                    isMainShow = true;
                }
                break;
        }
    }

    //设置Activity
    public void setActivity(MainActivity mainActivity) {
        this.mActivity = mainActivity;
    }
}
说明:Flags表示Window的属性,它有很多选项,通过这些选项可以控制Window的显示特性,这里主要介绍介个常用的选项:

FLAG_NOT_FOCUSABLE:

表示Window不需要获取焦点,也不需要接收各种输入事件,此标记会同时启用FLAG_NOT_TOUCH_MODAL,最终事件会直接传递给下层的具有焦点的Window。

FLAG_NOT_TOUCH_MODAL:

此模式下,系统会将当前Window区域以外的单击事件传递给底层的Window,当前Window区域以内的单击事件则自己处理。这个标记很重要,一般来说都需要开启此标记,否则其他Window将无法收到单击事件。

FLAG_SHOW_WHEN_LOCKED:

开启此模式,让Window显示在锁屏的界面上。

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        MyApplication application = (MyApplication) getApplication();
        application.setActivity(this);
    }
}
最后别忘了,加权限:

android:name="android.permission.SYSTEM_ALERT_WINDOW"/>



你可能感兴趣的:(Android)