Android9.0刘海屏适配

本文介绍了如何在Android应用中实现全屏模式、沉浸式状态栏,并针对刘海屏进行内容区域延伸和状态栏区的避让技巧,包括判断刘海屏、设置LAYOUT_IN_DISPLAY_CUTOUT_MODE及调整布局策略。
摘要由CSDN通过智能技术生成

沉浸式状态栏

  // 设置全屏
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        Window window = getWindow();
        window.setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.FLAG_FULLSCREEN);

        // 设置沉浸式
        int flags = View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN |
                View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
        int uiVisibility = window.getDecorView().getSystemUiVisibility();
        uiVisibility |= flags;
        window.getDecorView().setSystemUiVisibility(uiVisibility);

刘海区黑边(内容区域下挫)问题

让内容区域延伸到刘海区

	WindowManager.LayoutParams params = window.getAttributes();
	/**
	 * LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT 全屏模式,内容下移,非全屏不受影响
	 * LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES 允许内容区域延伸到刘海区
	 * LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER 不允许内容延伸进刘海区
	 */
	params.layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
	window.setAttributes(params); 

避开刘海区

// 避开刘海屏的两种方式
// 第一种: 设置布局第一个 View 的 topMargin 为状态栏的高度
// 第二种:设置布局跟View 的topPadding 为状态栏的高度

// 第一种
TextView topView = findViewById(R.id.top_view);
RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) topView.getLayoutParams();
layoutParams.topMargin = heightForDisplayCutout();
topView.setLayoutParams(layoutParams);
// 第二种
RelativeLayout containerView = findViewById(R.id.container);
containerView.setPadding(
        containerView.getPaddingLeft(),
        heightForDisplayCutout(),
        containerView.getPaddingRight(),
        containerView.getPaddingBottom());

适配刘海屏

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // 1.设置全屏
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        Window window = getWindow();
        window.setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.FLAG_FULLSCREEN);

        // 判断手机是否是刘海屏
        boolean hasDisplayCutout = hasDisplayCutout(window);
        if (hasDisplayCutout){
            // 2. 让内容区域延伸到刘海区
            WindowManager.LayoutParams params = window.getAttributes();
            /**
             * LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT 全屏模式,内容下移,非全屏不受影响
             * LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES 允许内容区域延伸到刘海区
             * LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER 不允许内容延伸进刘海区
             */
            params.layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
            window.setAttributes(params);

            // 3.设置沉浸式
            int flags = View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN |
                    View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
            int uiVisibility = window.getDecorView().getSystemUiVisibility();
            uiVisibility |= flags; // 追加沉浸式设置
            window.getDecorView().setSystemUiVisibility(uiVisibility);
        }
        setContentView(R.layout.layout_percent);

        // 避开刘海屏的两种方式
        // 第一种: 设置布局第一个 View 的 topMargin 为状态栏的高度
        // 第二种:设置布局跟View 的topPadding 为状态栏的高度

        // 第一种
        TextView topView = findViewById(R.id.top_view);
        RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) topView.getLayoutParams();
        layoutParams.topMargin = heightForDisplayCutout();
        topView.setLayoutParams(layoutParams);
        // 第二种
        RelativeLayout containerView = findViewById(R.id.container);
        containerView.setPadding(
                containerView.getPaddingLeft(),
                heightForDisplayCutout(),
                containerView.getPaddingRight(),
                containerView.getPaddingBottom());
    }

    /***
     * 是否是刘海屏
     * @param window
     * @return
     */
    @RequiresApi(api = Build.VERSION_CODES.P)
    private boolean hasDisplayCutout(Window window){
        WindowInsets insets = window.getDecorView().getRootWindowInsets();
        DisplayCutout displayCutout;
        // Android 9.0
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P && insets!=null){
            displayCutout = insets.getDisplayCutout();
            if (displayCutout!=null){
                if (displayCutout.getBoundingRects() !=null && displayCutout.getBoundingRects().size()>0 && displayCutout.getSafeInsetTop() > 0){
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * 计算状态栏高度(注:通常情况下,刘海的高度就是状态栏的高度)
     * @return
     */
    private int heightForDisplayCutout(){
        int resId = getResources().getIdentifier("status_bar_height", "dimen", "android");
        if (resId>0){
            return getResources().getDimensionPixelSize(resId);
        }
        return 96;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值