直播短视频系统,Android实现系统级全局的PopupWindow

直播短视频系统,Android实现系统级全局的PopupWindow
1. 清单文件声明权限

<!-- 显示顶层浮窗 -->

```handlebars
**<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>**
```

 

2. 全局的PopupWindow的布局文件(total_popup_window.xml ) :

```handlebars
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_gravity="center"
android:background="#ededed"
android:gravity="center"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout
android:id="@+id/popup_window"
android:layout_width="300dp"
android:layout_height="200dp"
android:background="#ffffff"
android:orientation="vertical" >
<TextView
android:id="@+id/title"
android:layout_width="match_parent"
android:layout_height="44dp"
android:gravity="center"
android:text="标题"
android:textColor="#000000"
android:textSize="18sp" />
<View
android:id="@+id/title_divider"
android:layout_width="match_parent"
android:layout_height="2dp"
android:layout_below="@id/title"
android:background="#ededed" />
<TextView
android:id="@+id/content"
android:layout_centerVertical="true"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:layout_below="@id/title_divider"
android:gravity="center"
android:padding="12dp"
android:text="这里展示的是内容"
android:textColor="#000000"
android:textSize="16sp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:orientation="horizontal"
android:paddingBottom="10dp"
android:paddingLeft="10dp"
android:paddingRight="10dp" >
<Button
android:id="@+id/negativeBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="#ededed"
android:focusable="true"
android:padding="10dp"
android:text="取消"
android:textColor="#000000"
android:textSize="16sp" />
<Button
android:id="@+id/positiveBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="18dp"
android:layout_weight="1"
android:background="#ed32"
android:focusable="true"
android:padding="10dp"
android:text="确定"
android:textColor="#000000"
android:textSize="16sp" />
</LinearLayout>
</RelativeLayout>
</LinearLayout>
```

 

3. WindowUtils

```handlebars
package com.example.hellowindow;
import android.content.Context;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnKeyListener;
import android.view.View.OnTouchListener;
import android.view.WindowManager;
import android.view.View.OnClickListener;
import android.view.WindowManager.LayoutParams;
import android.widget.Button;
/**
* 弹窗辅助类
* @ClassName WindowUtils
*/
public class WindowUtils {
private static final String LOG_TAG = "WindowUtils";
private static View mView = null;
private static WindowManager mWindowManager = null;
private static Context mContext = null;
public static Boolean isShown = false;
/**
* 显示弹出框
*
* @param context
* @param view
*/
public static void showPopupWindow(final Context context) {
if (isShown) {
LogUtil.i(LOG_TAG, "return cause already shown");
return;
}
isShown = true;
LogUtil.i(LOG_TAG, "showPopupWindow");
// 获取应用的Context
mContext = context.getApplicationContext();
// 获取WindowManager
mWindowManager = (WindowManager) mContext
.getSystemService(Context.WINDOW_SERVICE);
mView = setUpView(context);
final WindowManager.LayoutParams params = new WindowManager.LayoutParams();
// 类型
//params.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;//不兼容8.0
params.type = Build.VERSION.SDK_INT < Build.VERSION_CODES.O ?
WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY :
WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;//兼容了8.0
// WindowManager.LayoutParams.TYPE_SYSTEM_ALERT
// 设置flag
int flags = WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
// | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
// 如果设置了WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,弹出的View收不到Back键的事件
params.flags = flags;
// 不设置这个弹出框的透明遮罩显示为黑色
params.format = PixelFormat.TRANSLUCENT;
// FLAG_NOT_TOUCH_MODAL不阻塞事件传递到后面的窗口
// 设置 FLAG_NOT_FOCUSABLE 悬浮窗口较小时,后面的应用图标由不可长按变为可长按
// 不设置这个flag的话,home页的划屏会有问题
params.width = LayoutParams.MATCH_PARENT;
params.height = LayoutParams.MATCH_PARENT;
params.gravity = Gravity.CENTER;
mWindowManager.addView(mView, params);
LogUtil.i(LOG_TAG, "add view");
}
/**
* 隐藏弹出框
*/
public static void hidePopupWindow() {
LogUtil.i(LOG_TAG, "hide " + isShown + ", " + mView);
if (isShown && null != mView) {
LogUtil.i(LOG_TAG, "hidePopupWindow");
mWindowManager.removeView(mView);
isShown = false;
}
}
private static View setUpView(final Context context) {
LogUtil.i(LOG_TAG, "setUp view");
View view = LayoutInflater.from(context).inflate(R.layout.popupwindow,
null);
Button positiveBtn = (Button) view.findViewById(R.id.positiveBtn);
positiveBtn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
LogUtil.i(LOG_TAG, "ok on click");
// 打开安装包
// 隐藏弹窗
WindowUtils.hidePopupWindow();
}
});
Button negativeBtn = (Button) view.findViewById(R.id.negativeBtn);
negativeBtn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
LogUtil.i(LOG_TAG, "cancel on click");
WindowUtils.hidePopupWindow();
}
});
// 点击窗口外部区域可消除
// 这点的实现主要将悬浮窗设置为全屏大小,外层有个透明背景,中间一部分视为内容区域
// 所以点击内容区域外部视为点击悬浮窗外部
final View popupWindowView = view.findViewById(R.id.popup_window);// 非透明的内容区域
view.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
LogUtil.i(LOG_TAG, "onTouch");
int x = (int) event.getX();
int y = (int) event.getY();
Rect rect = new Rect();
popupWindowView.getGlobalVisibleRect(rect);
if (!rect.contains(x, y)) {
WindowUtils.hidePopupWindow();
}
LogUtil.i(LOG_TAG, "onTouch : " + x + ", " + y + ", rect: "
+ rect);
return false;
}
});
// 点击back键可消除
view.setOnKeyListener(new OnKeyListener() {
@Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
switch (keyCode) {
case KeyEvent.KEYCODE_BACK:
WindowUtils.hidePopupWindow();
return true;
default:
return false;
}
}
});
return view;
}
}
```

 

4. 调用

打开:需要动态申请权限

```handlebars
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (Settings.canDrawOverlays(PopupTestActivity.this)) {
WindowUtils.showPopupWindow(this);
} else {
//若没有权限,提示获取.
Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION);
Toast.makeText(PopupTestActivity.this,"需要取得权限以使用悬浮窗",Toast.LENGTH_SHORT).show();
startActivity(intent);
}

}else {
//SDK在23以下,不用管.
WindowUtils.showPopupWindow(this);
}
```

关闭

```handlebars
WindowUtils.hidePopupWindow();
```

以上就是直播短视频系统,Android实现系统级全局的PopupWindow, 更多内容欢迎关注之后的文章

posted @ 2021-07-23 15:05  云豹科技-苏凌霄  阅读(208)  评论(0编辑  收藏  举报