美文网首页
状态栏、导航栏、PopupWindow的使用

状态栏、导航栏、PopupWindow的使用

作者: 耑意儿 | 来源:发表于2021-03-25 14:19 被阅读0次
    目录:
    1、状态栏、标题栏、导航栏简介
    2、PopupWindow的基本使用
    
    image.png

    1. 状态栏、标题栏、导航栏简介

    绝对高度 = 高度 + 状态栏高度 + 导航栏高度
    RealHeight = Height + StatusBarHeight + NavigationBarHeight

    1.1 获取屏幕绝对高度:RealHeight

        public static int getScreenRealHeight(Context context) {
            WindowManager windowManager = (WindowManager) (context.getApplicationContext().getSystemService(Context.WINDOW_SERVICE));
            Display defaultDisplay = windowManager.getDefaultDisplay();
            Point point = new Point();
            defaultDisplay.getRealSize(point);
            return point.y;
        }
    

    1.2 获取屏幕高度:Height

        /**
         * 方法一:
         */
        public static int getScreenHeight(Context context) {
            DisplayMetrics dm = context.getResources().getDisplayMetrics();
            return dm.heightPixels;
        }
    
        /**
         * 方法二:
         */
        public static int getScreenHeight(Context context) {
            WindowManager windowManager = (WindowManager) (context.getApplicationContext().getSystemService(Context.WINDOW_SERVICE));
            Display defaultDisplay = windowManager.getDefaultDisplay();
            Point point = new Point();
            defaultDisplay.getSize(point);
            return point.y;
        }
    

    1.3 获取状态栏高度:StatusBarHeight

        /**
         * 利用反射获取状态栏高度
         */
        public static int getStatusBarHeight(Context context) {
            int result = 0;
            //获取状态栏高度的资源id
            int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android");
            if (resourceId > 0) {
                result = context.getResources().getDimensionPixelSize(resourceId);
            }
            return result;
        }
    

    1.4 获取导航栏高度:NavigationbarHeight

        /**
         * 获取虚拟操作拦(home等)高度
         */
        public static int getNavigationBarHeight(Activity activity) {
            if (!isNavigationBarShow(activity))
                return 0;
            int height = 0;
            Resources resources = activity.getResources();
            //获取NavigationBar的高度
            int resourceId = resources.getIdentifier("navigation_bar_height", "dimen", "android");
            if (resourceId > 0)
                height = resources.getDimensionPixelSize(resourceId);
    //        LogUtil.i("NavigationBar的高度:" + height);
            return height;
        }
    
    
        /**
         * 虚拟操作拦(home等)是否显示
         */
        public static boolean isNavigationBarShow(Activity activity) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
                Display display = activity.getWindowManager().getDefaultDisplay();
                Point size = new Point();
                Point realSize = new Point();
                display.getSize(size);
                display.getRealSize(realSize);
                return realSize.y != size.y;
            } else {
                boolean menu = ViewConfiguration.get(activity).hasPermanentMenuKey();
                boolean back = KeyCharacterMap.deviceHasKey(KeyEvent.KEYCODE_BACK);
                if (menu || back) {
                    return false;
                } else {
                    return true;
                }
            }
        }
    

    2. PopupWindow的基本使用注意事项

    • 避免麻烦,将锚点设置为一条线,或一个点
    场景一:无半透明背景,在锚点顶部弹出
    无半透明背景,在锚点顶部弹出
    public void showAsDropUp(View parent){
            int windowPos[] = calculatePopWindowPos(parent, fl_content);
            int xOff = 0;// 可以自己调整偏移
            windowPos[0] -= xOff;
            this.showAtLocation(parent, Gravity.TOP | Gravity.START,20, windowPos[1]);
        }
    
        /**
         * 计算出来的位置,y方向就在anchorView的上面和下面对齐显示,x方向就是与屏幕右边对齐显示
         * 如果anchorView的位置有变化,就可以适当自己额外加入偏移来修正
         * @param anchorView 呼出window的view
         * @param contentView  window的内容布局
         * @return window显示的左上角的xOff,yOff坐标
         */
        private static int[] calculatePopWindowPos(final View anchorView, final View contentView) {
            final int windowPos[] = new int[2];
            final int anchorLoc[] = new int[2];
            anchorView.getLocationOnScreen(anchorLoc);
            final int anchorHeight = anchorView.getHeight();
            // 获取屏幕的高宽
            final int screenHeight = ScreenUtils.getScreenHeight(anchorView.getContext());
            final int screenWidth = ScreenUtils.getScreenWidth(anchorView.getContext());
            contentView.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
            // 计算contentView的高宽
            final int windowHeight = contentView.getMeasuredHeight();
            final int windowWidth = contentView.getMeasuredWidth();
            // 判断需要向上弹出还是向下弹出显示
            final boolean isNeedShowUp = (screenHeight - anchorLoc[1] - anchorHeight < windowHeight);
            if (isNeedShowUp) {
                windowPos[0] = screenWidth - windowWidth;
                windowPos[1] = anchorLoc[1] - windowHeight;
            } else {
                windowPos[0] = screenWidth - windowWidth;
                windowPos[1] = anchorLoc[1] + anchorHeight;
            }
            return windowPos;
        }
    
    场景二:有半透明背景,在锚点底部弹出,背景占满余下屏幕

    假设出现窗口没准确出现在锚点下方,或者半透明背景没占满余下屏幕的情况,看看高度取值是否准确。


    有半透明背景,在锚点底部弹出,背景占满余下屏幕
    • 锚点下方显示窗口,且占满余下屏幕,背景半透明
    @Override
        public void showAsDropDown(View anchor) {
            try {
                final int anchorLoc[] = new int[2];
                anchor.getLocationOnScreen(anchorLoc); 
                // shFull = sh + statusBar + navigationBar
                int shFull = StatusBar.getScreenRealHeight(mContext);// 2340
                int sh = StatusBar.getScreenHeight(mContext);// 2130
                int statusBar = StatusBar.getStatusBarHeight(mContext);//80
                int navigationBar = ScreenUtils.getNavigationBarHeight(mActivity);//130
                
                int h = shFull - anchorLoc[1]; // 取(真实高度 - 锚点y轴)
                setHeight(h); // 重新设置PopupWindow高度
                super.showAsDropDown(anchor);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    

    相关文章

      网友评论

          本文标题:状态栏、导航栏、PopupWindow的使用

          本文链接:https://www.haomeiwen.com/subject/vdllhltx.html