WindowManager介绍
通过Context.getSystemService(Context.WINDOW_SERVICE)可以获得 WindowManager对象。
使用WindowManager可以在其他应用最上层,甚至手机桌面最上层显示窗口。
调用的是WindowManager继承自基类的addView方法和removeView方法来显示和隐藏窗口。
LayoutParams常用参数:
- type值
用于确定悬浮窗的类型,一般设为2002,表示在所有应用程序之上,但在状态栏之下。
- flags值
用于确定悬浮窗的行为,比如说不可聚焦,非模态对话框等等,属性非常多,大家可以查看文档。
- gravity值
用于确定悬浮窗的对齐方式,一般设为左上角对齐,这样当拖动悬浮窗的时候方便计算坐标。
- x值
用于确定悬浮窗的位置,如果要横向移动悬浮窗,就需要改变这个值。
- y值
用于确定悬浮窗的位置,如果要纵向移动悬浮窗,就需要改变这个值。
- width值
用于指定悬浮窗的宽度。
- 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>
参考文档
© 版权声明