近期,在做一款横屏卡牌游戏,游戏运行时,最左侧、最右侧(屏幕旋转)会被手机的刘海儿遮挡。为了不影响玩家的体验,需要做适配方案。
一、获取刘海儿高度,将左右的控件向中间移动刘海儿的高度。
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];
}
如果存在问题,欢迎大家指正、交流。
网友评论