美文网首页
刘海屏适配

刘海屏适配

作者: just0119 | 来源:发表于2019-03-08 17:35 被阅读0次
    • 适配逻辑


    对于有状态栏的页面不需要适配,因为刘海位置包含在状态栏高度中,我们需要适配的是没有状态栏的页面

    • 适配流程
      1. 应用页面设置使用刘海区显示
    <meta-data
        android:name="android.notch_support"
        android:value="true"/>
    或者使用代码
    /*刘海屏全屏显示FLAG*/
    public static final int FLAG_NOTCH_SUPPORT=0x00010000;
    /**
     * 设置应用窗口在华为刘海屏手机使用刘海区
     * @param window 应用页面window对象
     */
    public static void setFullScreenWindowLayoutInDisplayCutout(Window window) {
        if (window == null) {
            return;
        }
        WindowManager.LayoutParams layoutParams = window.getAttributes();
        try {
            Class layoutParamsExCls = Class.forName("com.huawei.android.view.LayoutParamsEx");
            Constructor con=layoutParamsExCls.getConstructor(LayoutParams.class);
            Object layoutParamsExObj=con.newInstance(layoutParams);
            Method method=layoutParamsExCls.getMethod("addHwFlags", int.class);
            method.invoke(layoutParamsExObj, FLAG_NOTCH_SUPPORT);
        } catch (ClassNotFoundException | NoSuchMethodException | IllegalAccessException |InstantiationException
                | InvocationTargetException e) {
            Log.e("test", "hw add notch screen flag api error");
        } catch (Exception e) {
            Log.e("test", "other Exception");
        }
    }
    
    2\. 设置屏幕最大宽高比
    
    
    <meta-data android:name="android.max_aspect"  android:value="2.4"/>
    
    
    3\. 判断是否为刘海屏,包括小米,华为,vivo等不同型号的检测
    
    /**
     * 判断是否是刘海屏
     */
    public static boolean hasNotchScreen(Context context){
        if(mChecked){
            return sHasNotchScreen;
        }
        if (hasNotchAtXiaomi(context) || hasNotchAtHuawei(context) || hasNotchAtOPPO(context)
                || hasNotchAtVivo(context)){ //|| isAndroidP(context) != null
            sHasNotchScreen = true;
        }
        else{
            sHasNotchScreen = false;//true for test, false is real!
        }
        sStatusHeight = getSystemStatusHeight(context);
        mChecked = true;
        return sHasNotchScreen;
    }
    
    
    4\. 获取高度并在页面设置占位高度
    
    
    if(ScreenNotchUtil.hasNotchScreen(this)){
        int i = ScreenNotchUtil.getNotchSize(this)[1];
        if(i>0){
            viewById.setHeight(i);
            viewById.setWidth(ViewGroup.LayoutParams.MATCH_PARENT);
            viewById.setBackgroundColor(Color.BLUE);
            viewById.setVisibility(View.VISIBLE);
        }
    }
    

    9.0 google刘海屏适配

    getSupportActionBar().hide();
    getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_FULLSCREEN | 
    View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN); 
    //设置页面全屏显示
    WindowManager.LayoutParams lp = getWindow().getAttributes();
    lp.layoutInDisplayCutoutMode = 
           WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES; 
    //设置页面延伸到刘海区显示
    getWindow().setAttributes(lp);
    
    • 附上完整工具类
    
    public class ScreenNotchUtil {
    
        public static final String ROM_MIUI = "MIUI";
        public static final String ROM_EMUI = "EMUI";
        public static final String ROM_FLYME = "FLYME";
        public static final String ROM_OPPO = "OPPO";
        public static final String ROM_SMARTISAN = "SMARTISAN";
        public static final String ROM_VIVO = "VIVO";
        public static final String ROM_QIKU = "QIKU";
    
        private static final String KEY_VERSION_MIUI = "ro.miui.ui.version.name";
        private static final String KEY_VERSION_EMUI = "ro.build.version.emui";
        private static final String KEY_VERSION_OPPO = "ro.build.version.opporom";
        private static final String KEY_VERSION_SMARTISAN = "ro.smartisan.version";
        private static final String KEY_VERSION_VIVO = "ro.vivo.os.version";
    
        static  boolean mChecked;
        static  boolean sHasNotchScreen;
        static int sStatusHeight = 0;
        /**
         * 判断是否是刘海屏
         */
        public static boolean hasNotchScreen(Context context){
            if(mChecked){
                return sHasNotchScreen;
            }
            if (hasNotchAtXiaomi(context) || hasNotchAtHuawei(context) || hasNotchAtOPPO(context)
                    || hasNotchAtVivo(context)){ //|| isAndroidP(context) != null
                sHasNotchScreen = true;
            }
            else{
                sHasNotchScreen = false;//true for test, false is real!
            }
            sStatusHeight = getSystemStatusHeight(context);
            mChecked = true;
            return sHasNotchScreen;
        }
    
        public static int getSystemStatusHeight(Context context)
        {
            try
            {
                if(mChecked){
                    return sStatusHeight;
                }
                Class<?> c = Class.forName("com.android.internal.R$dimen");
                Object obj = c.newInstance();
                Field field = c.getField("status_bar_height");
                int x = Integer.parseInt(field.get(obj).toString());
                int y = context.getResources().getDimensionPixelSize(x);
                return y;
            }
            catch (Exception e)
            {
                e.printStackTrace();
            }
            return 0;
        }
    
    
        public static void checkRom() {
            String brand = Build.BRAND.toUpperCase();
            String rom = null;
            if (!TextUtils.isEmpty(getProp(KEY_VERSION_MIUI))) {
                rom = ROM_MIUI;
            } else if (!TextUtils.isEmpty(getProp(KEY_VERSION_EMUI))) {
                rom = ROM_EMUI;
            } else if (!TextUtils.isEmpty(getProp(KEY_VERSION_OPPO))) {
                rom = ROM_OPPO;
            } else if (!TextUtils.isEmpty(getProp(KEY_VERSION_VIVO))) {
                rom = ROM_VIVO;
            } else {
                if (brand.contains("HUAWEI")) {
                    rom = ROM_EMUI;
                } else if (brand.contains("OPPO")) {
                    rom = ROM_OPPO;
                } else if (brand.contains("VIVO")) {
                    rom = ROM_VIVO;
                } else if (brand.contains("XIAOMI")) {
                    rom = ROM_MIUI;
                }
                else {
                    rom = Build.MANUFACTURER.toUpperCase();
                }
            }
        }
    
        public static String getProp(String name) {
            String line = null;
            BufferedReader input = null;
            try {
                Process p = Runtime.getRuntime().exec("getprop " + name);
                input = new BufferedReader(new InputStreamReader(p.getInputStream()), 1024);
                line = input.readLine();
                input.close();
            } catch (Exception ex) {
                return null;
            } finally {
                if (input != null) {
                    try {
                        input.close();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
            return line;
        }
    
        /**
         * 小米刘海屏判断.
         * @return 0 if it is not notch ; return 1 means notch
         * @throws IllegalArgumentException if the key exceeds 32 characters
         */
        private static int getInt(String key, Context context) {
            int result = 0;
            if (isXiaomi()){
                try {
                    ClassLoader classLoader = context.getClassLoader();
                    @SuppressWarnings("rawtypes")
                    Class SystemProperties = classLoader.loadClass("android.os.SystemProperties");
                    //参数类型
                    @SuppressWarnings("rawtypes")
                    Class[] paramTypes = new Class[2];
                    paramTypes[0] = String.class;
                    paramTypes[1] = int.class;
                    Method getInt = SystemProperties.getMethod("getInt", paramTypes);
                    //参数
                    Object[] params = new Object[2];
                    params[0] = new String(key);
                    params[1] = new Integer(0);
                    result = (Integer) getInt.invoke(SystemProperties, params);
    
                } catch (ClassNotFoundException e) {
                    e.printStackTrace();
                } catch (NoSuchMethodException e) {
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                } catch (IllegalArgumentException e) {
                    e.printStackTrace();
                } catch (InvocationTargetException e) {
                    e.printStackTrace();
                }
            }
            return result;
        }
    
        /**
         *小米刘海屏判断
         */
        public static boolean hasNotchAtXiaomi(Context context){
            boolean hasNotch = getInt("ro.miui.notch",context) == 1;
            return hasNotch;
        }
        /**
         * 华为刘海屏判断
         * @return
         */
        public static boolean hasNotchAtHuawei(Context context) {
            boolean ret = false;
            try {
                ClassLoader classLoader = context.getClassLoader();
                Class HwNotchSizeUtil = classLoader.loadClass("com.huawei.android.util.HwNotchSizeUtil");
                Method get = HwNotchSizeUtil.getMethod("hasNotchInScreen");
                ret = (boolean) get.invoke(HwNotchSizeUtil);
            } catch (ClassNotFoundException e) {
            } catch (NoSuchMethodException e) {
            } catch (Exception e) {
            } finally {
                return ret;
            }
        }
    
        public static final int VIVO_NOTCH = 0x00000020;//是否有刘海
        public static final int VIVO_FILLET = 0x00000008;//是否有圆角
    
        /**
         * VIVO刘海屏判断
         * @return
         */
        public static boolean hasNotchAtVivo(Context context) {
            boolean ret = false;
            try {
                ClassLoader classLoader = context.getClassLoader();
                Class FtFeature = classLoader.loadClass("android.util.FtFeature");
                Method method = FtFeature.getMethod("isFeatureSupport", int.class);
                ret = (boolean) method.invoke(FtFeature, VIVO_NOTCH);
            } catch (ClassNotFoundException e) {
            } catch (NoSuchMethodException e) {
            } catch (Exception e) {
            } finally {
                return ret;
            }
        }
        /**
         * OPPO刘海屏判断
         * @return
         */
        public static boolean hasNotchAtOPPO(Context context) {
            boolean hasNotch =  context.getPackageManager().hasSystemFeature("com.oppo.feature.screen.heteromorphism");
            return hasNotch;
        }
    
        /**
         * Android P 刘海屏判断
         */
        // 是否是小米手机
        public static boolean isXiaomi() {
            return "Xiaomi".equals(Build.MANUFACTURER);
        }
    
        /**
         * 获取刘海屏的尺寸信息
         * @param context
         * @return
         */
        public static int[] getNotchSize(Context context) {
    
            int[] ret = new int[]{0, 0};
    
            try {
    
                ClassLoader cl = context.getClassLoader();
    
                Class HwNotchSizeUtil = cl.loadClass("com.huawei.android.util.HwNotchSizeUtil");
    
                Method get = HwNotchSizeUtil.getMethod("getNotchSize");
    
                ret = (int[]) get.invoke(HwNotchSizeUtil);
    
            } catch (ClassNotFoundException ignored) {
    
            } catch (NoSuchMethodException ignored) {
    
            } catch (Exception ignored) {
    
            } finally {
    
                return ret;
    
            }
        }
    }
    
    
    76369452cd1980642084f15424306ab.jpg
    06303f33f818e849e7c618d3c9248b7.jpg

    相关文章

      网友评论

          本文标题:刘海屏适配

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