美文网首页
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