关于使用PopupWindow的一些问题

1.背景变暗

在弹出PopupWindow的时候,设置Window的alpha(透明度)和dim(暗淡值)两个值。

        final Window window = getWindow();
        final WindowManager.LayoutParams params = window.getAttributes();
        window.addFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
        params.dimAmount = 0.7f;
        params.alpha = 0.7f;
        window.setAttributes(params);
        popupWindow.setOnDismissListener(new PopupWindow.OnDismissListener() {
            @Override
            public void onDismiss() {
                params.dimAmount = 1.0f;
                params.alpha = 1.0f;
                window.setAttributes(params);
            }
        });
效果如下图所示:

2.具体位置

设置PoppupWindow在具体位置,可以调用popupWindow.showAtLocation(View, int, int, int)方法。

    /**
     * <p>
     * Display the content view in a popup window at the specified location. If the popup window
     * cannot fit on screen, it will be clipped. See {@link android.view.WindowManager.LayoutParams}
     * for more information on how gravity and the x and y parameters are related. Specifying
     * a gravity of {@link android.view.Gravity#NO_GRAVITY} is similar to specifying
     * <code>Gravity.LEFT | Gravity.TOP</code>.
     * </p>
     *
     * @param parent a parent view to get the {@link android.view.View#getWindowToken()} token from
     * @param gravity the gravity which controls the placement of the popup window
     * @param x the popup's x location offset
     * @param y the popup's y location offset
     */
    public void showAtLocation(View parent, int gravity, int x, int y) {
        showAtLocation(parent.getWindowToken(), gravity, x, y);
    }

其中,参数parent为PopupWindow关联的View;参数gravity为PopupWindow的位置(居左,居中,居右等);参数x为PopupWindow的x坐标偏移量;参数y为PopupWindow的y坐标偏移量。

在上面图中,PopupWindow显示在Button的左边位置,并且与Button对齐,具体代码为:

        int[] location = new int[2];
        button.getLocationInWindow(location);
        popupWindow.showAtLocation(button, Gravity.NO_GRAVITY, location[0] - contentView.getWidth(), location[1] - contentView.getMeasuredHeight() / 2 + button.getHeight() / 2);

注意:当contentView的宽或高为wrap_content时,要先测量contentView的宽高。测量方法如下:

contentView.measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
                View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));

实际上调用measure()方法时,会去调用onMeasure()方法,然后测量出View的大小。

public final void measure(int widthMeasureSpec, int heightMeasureSpec){}

参数widthMeasureSpec:表示父容器强加给的水平空间
参数heightMeasureSpec:表示父容器强加给的垂直空间

关于View.MeasureSpec.makeMeasureSpec(int, int)方法:

        public static int makeMeasureSpec(@IntRange(from = 0, to = (1 << MeasureSpec.MODE_SHIFT) - 1) int size,
                                          @MeasureSpecMode int mode) {}

参数size:是指在某种测量模式的规格大小
参数mode:是指在测量模式
另外,模式只有三种值:

  • UNSPECIFIED:父容器不对View有任何限制,要多大给多大。
  • EXACTLY:父容器检测出View所需要的精确大小,这个时候View的最终大小就是SpecSize(参数size)所指定的值。它对应于LayoutParams中的match_parent和具体的数值这两种模式。
  • AT_MOST:父容器指定了一个可用大小即SpecSize(参数size),View的大小不能大于这个值,具体是什么值要看不同View的具体实现。它对应于LayoutParams中的wrap_content。

3.动画

在使用动画时,如果PopupWindow从底部弹出:

popupWindow.showAtLocation(v.getRootView(), Gravity.BOTTOM, 0, 0);

那么在系统5.0以上,会出现在NavigationBar下面弹出或者被NavigationBar遮挡问题。如下图所示:

针对这个问题有如下解决方案:

在values-21/style.xml中的主题中添加:

<item name="android:windowDrawsSystemBarBackgrounds">false</item>

这个属性指示这个窗口是否负责绘制系统bar的背景。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
PopupWindowAndroid中非常常见的一种弹窗控件,可以在屏幕上方或下方弹出一个窗口,常用于菜单、提示、选择等场景。 在Service中使用PopupWindow需要注意以下几点: 1. 需要在Service中创建一个WindowManager对象,用于在屏幕上添加PopupWindow。 2. 在创建PopupWindow时,需要传入一个View对象作为弹出窗口的内容,可以通过LayoutInflater.from(context).inflate()方法获取。 3. 创建PopupWindow时需要指定宽度、高度、动画等属性。 4. 在PopupWindow弹出之后,需要设置其背景色为透明,否则会遮挡住其他View。 以下是一个在Service中使用PopupWindow的示例代码: ``` public class MyService extends Service { private WindowManager mWindowManager; private PopupWindow mPopupWindow; @Override public void onCreate() { super.onCreate(); mWindowManager = (WindowManager) getSystemService(WINDOW_SERVICE); } @Override public int onStartCommand(Intent intent, int flags, int startId) { showPopupWindow(); return super.onStartCommand(intent, flags, startId); } private void showPopupWindow() { // 通过LayoutInflater获取PopupWindow的内容View View contentView = LayoutInflater.from(this).inflate(R.layout.popup_content, null); // 创建PopupWindow,指定宽度、高度、动画等属性 mPopupWindow = new PopupWindow(contentView, ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); mPopupWindow.setAnimationStyle(R.style.PopupWindowAnimation); mPopupWindow.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT)); mPopupWindow.setFocusable(true); // 在屏幕上添加PopupWindow mWindowManager.addView(mPopupWindow.getContentView(), getLayoutParams()); // 设置PopupWindow的位置 int x = 0; int y = 0; mPopupWindow.showAtLocation(getWindow().getDecorView(), Gravity.CENTER, x, y); } @Override public void onDestroy() { super.onDestroy(); if (mPopupWindow != null) { mWindowManager.removeView(mPopupWindow.getContentView()); } } private WindowManager.LayoutParams getLayoutParams() { WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams(); layoutParams.format = PixelFormat.TRANSLUCENT; layoutParams.flags = WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH; layoutParams.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY; layoutParams.width = WindowManager.LayoutParams.WRAP_CONTENT; layoutParams.height = WindowManager.LayoutParams.WRAP_CONTENT; return layoutParams; } } ``` 在上述代码中,我们首先通过LayoutInflater获取PopupWindow的内容View,然后创建PopupWindow并设置其宽度、高度、动画等属性。接着,我们使用WindowManager将PopupWindow添加到屏幕上,并设置其位置为屏幕中央。最后,在Service销毁时,需要手动移除PopupWindow

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值