Android 解决底部弹出PopWindow时如果有虚拟按键遮挡问题

弹出PopWindow时如果手机有虚拟按键可能会出现虚拟按键遮挡住popwindow的布局,导致pop显示不全:
错误显示

解决办法:设置PopWindow显示的Y轴的位置为虚拟按键高度的位置。下面是获取虚拟按键高度的方法:

    /**
     * Desc: 获取虚拟按键高度 放到工具类里面直接调用即可
     */
    public static int getNavigationBarHeight(Context context) {
        int result = 0;
        if (hasNavBar(context)) {
            Resources res = context.getResources();
            int resourceId = res.getIdentifier("navigation_bar_height", "dimen", "android");
            if (resourceId > 0) {
                result = res.getDimensionPixelSize(resourceId);
            }
        }
        LogUtils.e("虚拟键盘高度"+result);
        return result;
    }

    /**
     * 检查是否存在虚拟按键栏
     *
     * @param context
     * @return
     */
    @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
    public static boolean hasNavBar(Context context) {
        Resources res = context.getResources();
        int resourceId = res.getIdentifier("config_showNavigationBar", "bool", "android");
        if (resourceId != 0) {
            boolean hasNav = res.getBoolean(resourceId);
            // check override flag
            String sNavBarOverride = getNavBarOverride();
            if ("1".equals(sNavBarOverride)) {
                hasNav = false;
            } else if ("0".equals(sNavBarOverride)) {
                hasNav = true;
            }
            return hasNav;
        } else { // fallback
            return !ViewConfiguration.get(context).hasPermanentMenuKey();
        }
    }

    /**
     * 判断虚拟按键栏是否重写
     *
     * @return
     */
    private static String getNavBarOverride() {
        String sNavBarOverride = null;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            try {
                Class c = Class.forName("android.os.SystemProperties");
                Method m = c.getDeclaredMethod("get", String.class);
                m.setAccessible(true);
                sNavBarOverride = (String) m.invoke(null, "qemu.hw.mainkeys");
            } catch (Throwable e) {
            }
        }
        return sNavBarOverride;
    }

然后在显示PonWindow的地方调用:

    popwindow.showAtLocation(findViewById(R.id.layout),
                             Gravity.BOTTOM,
                             0,
                             getNavigationBarHeight(Context context));

修改后的效果:
正确显示

方法参考:http://www.cnblogs.com/ldq2016/p/6905429.html

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
好的,可以通过弹出一个带有指示器的PopupWindow来实现。 在VerticalSeekBar类中添加以下代码: ```java private PopupWindow popupWindow; private TextView textView; public void showIndicator(int progress) { if (popupWindow == null) { textView = new TextView(getContext()); textView.setTextColor(Color.WHITE); textView.setTextSize(14); textView.setGravity(Gravity.CENTER); textView.setBackgroundResource(R.drawable.seekbar_indicator_bg); popupWindow = new PopupWindow(textView, LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); popupWindow.setOutsideTouchable(true); popupWindow.setFocusable(false); } int[] location = new int[2]; getLocationOnScreen(location); int thumbTop = (int) ((getHeight() - getThumb().getIntrinsicHeight()) * 0.5f); int thumbLeft = (int) ((getWidth() - getThumb().getIntrinsicWidth()) * 0.5f); int thumbWidth = getThumb().getIntrinsicWidth(); int thumbHeight = getThumb().getIntrinsicHeight(); int indicatorWidth = dp2px(getContext(), 40); int indicatorHeight = dp2px(getContext(), 20); int indicatorX = location[0] - indicatorWidth - thumbWidth; int indicatorY = location[1] + (getHeight() - indicatorHeight) * progress / getMax() - thumbTop; textView.setText(String.valueOf(progress)); popupWindow.showAtLocation(this, Gravity.NO_GRAVITY, indicatorX, indicatorY); } public void hideIndicator() { if (popupWindow != null) { popupWindow.dismiss(); } } private int dp2px(Context context, int dp) { float density = context.getResources().getDisplayMetrics().density; return (int) (dp * density + 0.5f); } ``` 在Activity中,可以这样使用: ```java VerticalSeekBar verticalSeekBar = findViewById(R.id.vertical_seekbar); verticalSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { verticalSeekBar.showIndicator(progress); } @Override public void onStartTrackingTouch(SeekBar seekBar) { } @Override public void onStopTrackingTouch(SeekBar seekBar) { verticalSeekBar.hideIndicator(); } }); ``` 在onProgressChanged()方法中弹出PopupWindow,并在PopupWindow中显示进度值。在onStopTrackingTouch()方法中隐藏PopupWindow。 这样就可以通过弹出PopupWindow在滑块旁边显示进度值了。PopupWindow的位置使用了SeekBar的getLocationOnScreen()方法和一些计算。PopupWindow的大小为40dp * 20dp,背景使用了一个Drawable资源。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值