1.自定义view
public class RecommendWindow extends FrameLayout {
private Context mContext;
private TextView mTvContent;
private TextView mTvStart;
public RecommendWindow(@NonNull Context context) {
super(context);
mContext = context;
initView();
}
public RecommendWindow(@NonNull Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
mContext = context;
initView();
}
public RecommendWindow(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
mContext = context;
initView();
}
public RecommendWindow(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
mContext = context;
initView();
}
private void initView() {
LayoutInflater inflater = LayoutInflater.from(mContext.getApplicationContext());
FrameLayout frameLayout = (FrameLayout) inflater.inflate(R.layout.view_background_recommend, this);
mTvContent = frameLayout.findViewById(R.id.tv_common_content);
mTvStart = frameLayout.findViewById(R.id.tv_common_go);
}
public TextView getTvContent() {
return mTvContent;
}
public TextView getTvStart() {
return mTvStart;
}
}
# 获取自定义view对象:
mRecommendWindow = new RecommendWindow(mContext);
也可以使用其他构造函数,自定义其他的属性。
2.获取WindowManager对象
mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
3. 获取LayoutParams对象
WindowManager.LayoutParams layoutParams = FloatWindowUtil.getWindowLayoutParams(0, -268, 1200, 120);
# 这里是自己封装了一个方法,传入的参数是悬浮窗的位置和宽高
/** * 定义浮窗的宽高和位置 * * @param x 浮窗中心点x坐标 * @param y 浮窗中心点y坐标 * @param width 浮窗宽度 * @param height 浮窗高度 * @return LayoutParams */ public static WindowManager.LayoutParams getWindowLayoutParams(int x, int y, int width, int height) { WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams( width, height, WindowManager.LayoutParams.TYPE_SYSTEM_ERROR, WindowManager.LayoutParams.FLAG_FULLSCREEN | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED | WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, PixelFormat.TRANSLUCENT); // 位置的坐标如果是X=0 Y=0的话 那么弹出位置就是中间, // x负数的话就是向左,x正数就是向右,y负数就是向上,y正数向下为, // 且当偏移超出了屏幕时,会把Dialog的边靠在屏幕的边上,不会出去也不会压缩。 layoutParams.x = x; layoutParams.y = y; return layoutParams; }
# WindowManager.LayoutParams.TYPE_SYSTEM_ERROR:悬浮窗显示层级,可自己决定,前提在清单文件里得添加权限。
# WindowManager.LayoutParams.FLAG_FULLSCREEN:全屏属性
# WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE:焦点获取
# PixelFormat.TRANSLUCENT:如果是非全屏窗口,并且需要蒙层,则必须是这个属性
4.显示窗口,并做事件处理
mWindowManager.addView(mRecommendWindow, layoutParams);
mRecommendWindow.getTvContent().setText(content);
mRecommendWindow.getTvStart().setOnClickListener(v -> {
recommendListener.onOpen();
dismissRecommendDialog();
});
以上就是悬浮窗的简单实现。
另外遇到一个问题,在一个全屏应用上,显示非全屏悬浮窗时,想要弹出输入法,则导航栏必定会出来,目前没有找到好的解决办法。