WindowManager介绍

通过Context.getSystemService(Context.WINDOW_SERVICE)可以获得 WindowManager对象。

使用WindowManager可以在其他应用最上层,甚至手机桌面最上层显示窗口。

调用的是WindowManager继承自基类的addView方法和removeView方法来显示和隐藏窗口。

LayoutParams常用参数:

  1. type值

用于确定悬浮窗的类型,一般设为2002,表示在所有应用程序之上,但在状态栏之下。

  1. flags值

用于确定悬浮窗的行为,比如说不可聚焦,非模态对话框等等,属性非常多,大家可以查看文档。

  1. gravity值

用于确定悬浮窗的对齐方式,一般设为左上角对齐,这样当拖动悬浮窗的时候方便计算坐标。

  1. x值

用于确定悬浮窗的位置,如果要横向移动悬浮窗,就需要改变这个值。

  1. y值

用于确定悬浮窗的位置,如果要纵向移动悬浮窗,就需要改变这个值。

  1. width值

用于指定悬浮窗的宽度。

  1. height值

用于指定悬浮窗的高度。

WindowManager实现悬浮窗

声明权限

AndroidManifest.xml中添加如下代码

<!-- 显示顶层浮窗 -->
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />

注意:

Android 6.0以上【非系统应用】,需要在[系统设置]找到[应用和通知]已经的[我们的应用],然后点击进入[高级],打开[在应用上方显示]开关

demo代码片段

MainActivity.java

public class WindowActivity extends Activity {

    private String TAG = getClass().getSimpleName();

    private WindowManager windowManager;
    private WindowManager.LayoutParams mLayoutParams = null;
    private View seekbarLayoutView = null;
    private boolean hasWindow = false;
    private LayoutInflater inflater = null;


    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.d(TAG, "onCreate : ");
        setContentView(R.layout.activity_main);
        initUI();
        initWindow();
    }

    @Override
    protected void onResume() {
        super.onResume();
        Log.d(TAG, "onResume: ");
    }

    @Override
    protected void onPause() {
        super.onPause();
        Log.d(TAG, "onPause: ");
    }

    @Override
    protected void onStop() {
        super.onStop();
        Log.d(TAG, "onStop: ");
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.d(TAG, "onDestroy: ");
    }

    private void initUI() {

        findViewById(R.id.main_bt_one).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Log.d(TAG, "onClick  show(): ");
                show();
            }
        });

        return;
    }

    private void initWindow() {
        inflater = LayoutInflater.from(getApplicationContext());
        windowManager = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
        mLayoutParams = new WindowManager.LayoutParams();

        //设置透明度
        mLayoutParams.alpha = 1.0f;

        //Android 6.0后,非系统应用,需要在[系统设置]找到[应用和通知]已经的[我们的应用],然后点击进入[高级],打开[在应用上方显示]开关
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {//6.0 以上
            mLayoutParams.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
        } else {
            mLayoutParams.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;
        }

        mLayoutParams.flags = WindowManager.LayoutParams.FLAG_FULLSCREEN;

        mLayoutParams.width = ViewGroup.LayoutParams.MATCH_PARENT;
        mLayoutParams.height = ViewGroup.LayoutParams.MATCH_PARENT;
        seekbarLayoutView = inflater.inflate(R.layout.topbar_layout, null);
        seekbarLayoutView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Log.d(TAG, "onClick hide(): ");
                hide();
            }
        });
        return;
    }

    private void show() {
        Log.d(TAG, "show hasWindow : " + hasWindow);
        if (null != windowManager && (null != seekbarLayoutView) &&
                (seekbarLayoutView.getParent() == null) && !hasWindow) {
            hasWindow = true;
            windowManager.addView(seekbarLayoutView, mLayoutParams);
        }
        return;
    }

    private void hide() {
        Log.d(TAG, "hide hasWindow : " + hasWindow);
        if (null != windowManager && (null != seekbarLayoutView) && hasWindow) {
            windowManager.removeView(seekbarLayoutView);
            hasWindow = false;
        }
        return;
    }

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:background="@android:color/darker_gray"
    android:orientation="vertical">


    <Button
        android:id="@+id/main_bt_one"
        android:layout_width="match_parent"
        android:layout_height="60dp"
        android:gravity="center"
        android:text="one" />

</LinearLayout>

topbar_layout.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@android:color/holo_green_dark"
    android:paddingTop="160dp"
    tools:ignore="MissingDefaultResource">

</RelativeLayout>

参考文档

  1. WindowManager.LayoutParams
  2. Android 之 Window、WindowManager 与窗口管理

相关文章

暂无评论

none
暂无评论...