美文网首页
Android、iOS刘海儿屏适配

Android、iOS刘海儿屏适配

作者: _灯下影子 | 来源:发表于2018-12-17 23:10 被阅读0次

    近期,在做一款横屏卡牌游戏,游戏运行时,最左侧、最右侧(屏幕旋转)会被手机的刘海儿遮挡。为了不影响玩家的体验,需要做适配方案。

    一、获取刘海儿高度,将左右的控件向中间移动刘海儿的高度。
    1.获取手机是否带刘海儿
    2.获取刘海儿高度
    3.设置控件的位置

    源码奉上:Android

    package util;
    import android.os.Build;
    import android.util.Log;
    import android.view.Display;
    import org.cocos2dx.lib.Cocos2dxActivity;
    import java.lang.reflect.Method;
    
    public class AdjustAndroidNotchScreen {
    
        public static String hasIphoneAdjustNotchScreenHeight()
        {
            int notchHeight = 0;
            String brand = Build.BRAND;//获取设备品牌
            String model = Build.MODEL;//获取手机的型号
            String displayStr = Build.DISPLAY;//获取分辨率
            Log.e("brand:",brand);
            Log.e("model:",model);
            Log.e("displayStr:",displayStr); 
            //小米手机、刘海儿屏的高度等于状态栏高度
            if (brand.equals("Xiaomi") && hasNotchInXiaomi()) {
                notchHeight = getStatusBarHeight();
            }
            else if ( brand.equals("vivo") && hasNotchInScreenAtVoio())
            {
                notchHeight = getStatusBarHeight();
            }
            else if ( brand.equals("OPPO") && hasNotchInOppo())
            {
                notchHeight = getStatusBarHeight();
            }
            else if ( brand.equals("HUAWEI") && hasNotchInHuawei())
            {
                //获取刘海尺:width、heightint; [0]值为刘海宽度int;[1]值为刘海高度
                notchHeight = getNotchSizeHuawei()[1];
            }//三星手机特殊处理(width/height > 2.1 但是没有刘海儿)
            else if ( brand.equals("samsung") )
            {
                //暂时没有刘海屏
                notchHeight = 0;
            }
            else
            {
                //剩余的机型,(截止2018.12.17 据统计width/height > 2.0 都存在刘海儿)
                Display display = Cocos2dxActivity.getTheActivity().getWindowManager().getDefaultDisplay();
                int disWidth = display.getWidth();
                int disHeight = display.getHeight();
                System.out.println("width-display :" + disWidth);
                System.out.println("heigth-display :" + disHeight);
                if (disHeight/disWidth > 2.0) {
                    notchHeight = 44;
                }else {
                    notchHeight = 0;
                }
            }
            Log.e("zh_wj notchHeight:",String.valueOf(notchHeight));
            return String.valueOf(notchHeight);
        }
    
        //xiaomi 机型是否有刘海
        public static boolean hasNotchInXiaomi()
        {
            return getProperty("ro.miui.notch", "0").equals("1");
        }
        //反射机制获取SystemProperties
        public static  String getProperty(String key, String defaultValue) {
            String value = defaultValue;
            try {
                Class<?> c = Class.forName("android.os.SystemProperties");
                Method get = c.getMethod("getInt", String.class, String.class);
                value = (String)(get.invoke(c, key, "unknown" ));
            } catch (Exception e) {
                e.printStackTrace();
            }finally {
                return value;
            }
        }
    
        // oppo 机型是否有刘海
        public static boolean hasNotchInOppo() {
            return Cocos2dxActivity.getTheActivity().getPackageManager().hasSystemFeature("com.oppo.feature.screen.heteromorphism");
        }
    
        // vivo 机型是否有刘海
        public static final int NOTCH_IN_SCREEN_VOIO=0x00000020;//是否有凹槽
        public static final int ROUNDED_IN_SCREEN_VOIO=0x00000008;//是否有圆角
        public static boolean hasNotchInScreenAtVoio(){
            boolean ret = false;
            try {
                ClassLoader cl = Cocos2dxActivity.getTheActivity().getClassLoader();
                Class FtFeature = cl.loadClass("com.util.FtFeature");
                Method get = FtFeature.getMethod("isFeatureSupport",int.class);
                Object objTmp = get.invoke(FtFeature,NOTCH_IN_SCREEN_VOIO);
                if (objTmp == null) {
                    ret = false;
                } else { ret = true; }
            } catch (ClassNotFoundException e)
            { Log.e("test", "hasNotchInScreen ClassNotFoundException"); }
            catch (NoSuchMethodException e)
            { Log.e("test", "hasNotchInScreen NoSuchMethodException"); }
            catch (Exception e)
            { Log.e("test", "hasNotchInScreen Exception"); }
            finally
            { return ret; }
        }
    
        //华为手机是否有刘海
        public static boolean hasNotchInHuawei() {
            boolean hasNotch = false;
            try {
                ClassLoader cl = Cocos2dxActivity.getTheActivity().getClassLoader();
                Class HwNotchSizeUtil = cl.loadClass("com.huawei.android.util.HwNotchSizeUtil");
                Method hasNotchInScreen = HwNotchSizeUtil.getMethod("hasNotchInScreen");
                if(hasNotchInScreen != null) {
                    Object objTmp = hasNotchInScreen.invoke(HwNotchSizeUtil);
                    if (objTmp == null){
                        hasNotch = false;
                    }else{ hasNotch = true;}
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            return hasNotch;
        }
    
        public static int[] getNotchSizeHuawei() {
            int[] ret = new int[]{0, 0};
            try {
                ClassLoader cl = Cocos2dxActivity.getTheActivity().getClassLoader();
                Class HwNotchSizeUtil = cl.loadClass("com.huawei.android.util.HwNotchSizeUtil");
                Method get = HwNotchSizeUtil.getMethod("getNotchSize");
                ret = (int[]) get.invoke(HwNotchSizeUtil);
            } catch (ClassNotFoundException e) {
                Log.e("test", "getNotchSize ClassNotFoundException");
            } catch (NoSuchMethodException e) {
                Log.e("test", "getNotchSize NoSuchMethodException");
            } catch (Exception e) {
                Log.e("test", "getNotchSize Exception");
            } finally {
                return ret;
            }
        }
    
    
        //获取状态栏的高度
        private static int getStatusBarHeight() {
            int statusBarHeight = 0;
            int resourceId = Cocos2dxActivity.getTheActivity().getResources().getIdentifier("status_bar_height", "dimen", "android");
            if (resourceId > 0) {
                statusBarHeight = Cocos2dxActivity.getTheActivity().getResources().getDimensionPixelSize(resourceId);
            }
            return statusBarHeight;
        }
    }
    

    IOS:

    //获取刘海屏 刘海的高度
    +(NSString* ) getIPhoneNotchScreenHeight
    {
    //iOS 11 以下的默认不存在刘海儿(没有谁iphone X 刷回ios 10 系统吧。哈哈)
        if (__IPHONE_OS_VERSION_MAX_ALLOWED < __IPHONE_11_0) {
            return @"0";
        }
        
        /* iPhone8 Plus  UIEdgeInsets: {20, 0, 0, 0}
         * iPhone8       UIEdgeInsets: {20, 0, 0, 0}
         * iPhone XR     UIEdgeInsets: {44, 0, 34, 0}
         * iPhone XS     UIEdgeInsets: {44, 0, 34, 0}
         * iPhone XS Max UIEdgeInsets: {44, 0, 34, 0}
         */
    //ios 11 以上提供专门方法获取刘海儿高度
        UIEdgeInsets safeAreaInsets = UIApplication.sharedApplication.windows.firstObject.safeAreaInsets;
        
        CGFloat bottomSpace = 0;
        switch (UIApplication.sharedApplication.statusBarOrientation) {
            case UIInterfaceOrientationPortrait:{
                bottomSpace = safeAreaInsets.bottom;
            }break;
            case UIInterfaceOrientationLandscapeLeft:{
                bottomSpace = safeAreaInsets.right;
            }break;
            case UIInterfaceOrientationLandscapeRight:{
                bottomSpace = safeAreaInsets.left;
            } break;
            case UIInterfaceOrientationPortraitUpsideDown:{
                bottomSpace = safeAreaInsets.top;
            }break;
            default:
                bottomSpace = safeAreaInsets.bottom;
                break;
        }
        return [NSString stringWithFormat:@"%f",bottomSpace];
    }
    

    如果存在问题,欢迎大家指正、交流。

    相关文章

      网友评论

          本文标题:Android、iOS刘海儿屏适配

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