刘海屏适配
2019-03-08 本文已影响0人
just0119
-
适配逻辑
对于有状态栏的页面不需要适配,因为刘海位置包含在状态栏高度中,我们需要适配的是没有状态栏的页面
- 适配流程
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