Android刘海屏适配方案

1 什么是刘海屏

(1)屏幕的正上方居中位置(下图黑色区域)会被挖掉一个孔,屏幕被挖掉的区域无法正常显示内容,这种类型的屏幕就是刘海屏,也有其他叫法:挖孔屏、凹凸屏等等,这里统一按刘海屏命名。
(2)现在市场上的情况来说,“刘海屏”主要分成两类,一类是标准的 Android P Api,另外一类就是厂商在 Android P 以下的系统,做的特殊适配。

2 刘海屏适配方案

2.1 需要适配刘海屏的页面

(1)对于有状态栏的页面:不会受到刘海屏特性的影响,因为刘海屏包含在状态栏中了;
(2)全屏显示的页面,主要适配的是:①启动页;②引导页;③阅读器,重点是阅读器

2.2 刘海屏布局及安全区域说明

在这里插入图片描述

2.3 参考链接

android 兼容所有刘海屏的方案大全

3 刘海屏适配方案接入步骤(共3步)

3.1 升级Version到28(已修改)

android {
    compileSdkVersion 28
    buildToolsVersion "28.0.3"

    defaultConfig {
        minSdkVersion 14
        targetSdkVersion 23
    }
}

dependencies {
    compile fileTree(include: ['*.jar'], dir: 'libs')
    compile 'com.android.support:design:28.0.0'
    compile 'com.android.support:appcompat-v7:28.0.0'
    compile 'com.android.support:support-v4:28.0.0'
}

3.2 应用页面设置使用刘海区显示

3.2.1 方案一:在应用的AndroidManifest.xml中增加meta-data属性

此属性不仅可以针对Application生效,也可以对Activity配置生效。弊端:对Application生效,意味着该应用的所有页面,系统都不会做竖屏场景的特殊下移或者是横屏场景的右移特殊处理,也不能针对某页面做特殊处理。

       <!-- Android O刘海适配 start -->
        <!-- 华为 -->
        <meta-data
            android:name="android.notch_support"
            android:value="true" />
        <!-- 华为 -->
        
        <!-- 小米 -->
        <meta-data
            android:name="notch.config"
            android:value="portrait|landscape" />
        <!-- 小米 -->
        <!-- Android O刘海适配 end -->

        <!-- Android全面屏全屏 start -->
        <meta-data
            android:name="android.max_aspect"
            android:value="2.2" />
        <!-- Android全面屏全屏 end -->
3.2.2 方案二:动态增加/清除刘海屏flag,请求扩展到刘海区显示/不扩展到刘海区显示
    /**
     *  NotchManager.listenOnChange()
     * 
     * 动态地增加/清除相关的flag,请求使用刘海区显示/不使用刘海区显示
     */
    private static void listenOnChange(Activity activity) {
        if (mNotchUsable) {
            NotchJudgementUtil.addNotchFlag(activity);
        } else {
            NotchJudgementUtil.clearNotchFlag(activity);
        }
    }
3.2.3 小书亭的方案——动态增加/清除刘海屏(建议)

(1) 在应用的AndroidManifest.xml中增加meta-data属性

 <!-- Android全面屏全屏 start -->
        <meta-data
            android:name="android.max_aspect"
            android:value="2.2" />
 <!-- Android全面屏全屏 end -->

(2)使用NotchManager类中的初始化方法:initNotchListener()调用listenOnChange()(initNotchListener()方法已实现);

3.3 在Activity的父类初始化“NotchManager”和添加setFullScreen()方法(已修改)

public class BaseFragmentActivity extends AppCompatActivity {

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

    @Override
    protected void onResume() {
        super.onResume();
        // 初始化Android O,P刘海屏适配管理类
        NotchManager.initNotchListener(this);
    }

    /**
     * 因为刘海屏适配的问题,设置Activity全屏有且只可以使用此方法
     */
    public void setFullScreen(boolean fullScreen) {
        // 设置是否全屏
        if (fullScreen) {
            WindowManager.LayoutParams attr = getWindow().getAttributes();
            attr.flags |= WindowManager.LayoutParams.FLAG_FULLSCREEN;
            getWindow().setAttributes(attr);
        } else {
            final WindowManager.LayoutParams attrs = getWindow().getAttributes();
            attrs.flags &= (~WindowManager.LayoutParams.FLAG_FULLSCREEN);
            getWindow().setAttributes(attrs);
        }

        // 必须在设置状态栏之后设置,使可以绘制到刘海区域
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
            NotchJudgementUtil.setAndroidPDisplayCutoutMode(getWindow(), WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES);

            // 设置SystemUi
            if (fullScreen) {
                View decorView = getWindow().getDecorView();
                int systemUiVisibility = decorView.getSystemUiVisibility();
                systemUiVisibility |= View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
                getWindow().getDecorView().setSystemUiVisibility(systemUiVisibility);
            } else {
                View decorView = getWindow().getDecorView();
                int systemUiVisibility = decorView.getSystemUiVisibility();
                systemUiVisibility &= (~View.SYSTEM_UI_FLAG_FULLSCREEN);
                systemUiVisibility &= (~View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
                systemUiVisibility &= (~View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
                getWindow().getDecorView().setSystemUiVisibility(systemUiVisibility);
            }
        }
    }
}

4 具体的适配策略(已修改)

4.1 适配启动页

4.1.1 在onCreate()调用setFullScreen(true)
/**
 * 在设置全屏的Activity中调用setFullScreen(true)
 */
public class SplashActivity extends BaseFragmentActivity {

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);  
        
        // 调用父类的setFullScreen方法设置是否全屏
        setFullScreen(true);
    }
}
4.1.2 启动页添加V28下style主题
<!-- 启动页冷启动适配Android P -->
    <style name="XstSplashTheme" parent="XstAppTheme">
        // default/shortEdges/never
        <item name="android:windowLayoutInDisplayCutoutMode">shortEdges</item>
    </style>

参考链接:Android P 凹口屏支持,打造全面屏体验

4.1.3 新增drawable-xxhdpi-2034x1080资源文件夹放18:9的占位图

在这里插入图片描述
参考链接:全面屏Splash/占位图适配/全面屏/刘海屏笔记

4.2 适配引导页

4.2.1 类似启动页,在onCreate()调用setFullScreen(true)
4.2.2 新增drawable-xxhdpi-2034x1080资源文件夹放18:9的占位图

在这里插入图片描述

4.3 适配阅读器

4.3.1 在onCreate()调用setFullScreen(true)(参考)

(1)在onCreate()设置全屏的Activity中调用setFullScreen(true)

public abstract class BaseReadActivity {
	@Override
    protected void onCreate(Bundle savedInstanceState) {
		// 设置全屏与否
        setFullscreen();
	}
}

&#

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值