react native 安卓(特别是小米手机)全面屏是否开虚拟按键的适配
react native 安卓(特别是小米手机)全面屏是否开虚拟按键的适配
做rn蛮久了,遇到的坑无数,谢谢大家带我爬过的坑,这次我也来分享一下,希望帮助到有需要的人!
大家先看先后效果对比:
没开虚拟按键的时候完美:
开了虚拟按键之后,显示不全了:
处理之后的效果:
产生的原因:
andorid全面屏幕中 Dimensions.get(‘window’).height 计算屏幕高度时会自动减少StatusBar 的高度
解决方案:
const { width,height } = Dimensions.get('window');
let deviceHeight = height/width > 1.8 ? height+ NativeModules.StatusBarManager.HEIGHT: height;
然后将deviceHeight设成我们的内容高度就行了!
到这里我以为完美解决了哈哈,其实还有另一个大坑等着呢!
测试了几乎所有主流机型,基本都没问题很完美,唯独小米手机,真的是坑啊!
这时候小米全面屏手机开启虚拟按键的状态是对的,可是没开按键的时候下面没有铺满,缺了一大截,其原因就是它不管开不开按键它的height/width 都大于 1.8 ,因为它的Dimensions.get(‘window’).height不随开不开按键而变化,始终是那个那么高,所以根本无法用这个比例来判断了!
查阅很多资料,rn不好解决了,只能用调用原生方法试试了,结果终于完美解决,步骤我也给大家贴出来:
1.在com.xx.xx创建包名milletAdaptation;
编写 Module,在milletAdaptation包下创建MilletAdaptation.java,代码如下:
package com.项目工程名.milletAdaptation;import android.app.Activity;
import android.content.Context;
import android.os.Build;
import android.os.Bundle;
import android.provider.Settings;
import android.util.DisplayMetrics;
import android.view.Display;
import android.view.WindowManager;
import com.facebook.react.ReactApplication;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.Promise;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.swordsmanapp.MainActivity;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import java.lang.reflect.Method;public class MilletAdaptation extends ReactContextBaseJavaModule{DisplayMetrics metrics = new DisplayMetrics();public MilletAdaptation(ReactApplicationContext reactContext) {super(reactContext);}@NonNull@Overridepublic String getName() {return "MilletAdaptation";}@ReactMethodpublic void getHeight(final Promise promise) {int height = metrics.heightPixels;Activity activty = MainActivity.getActivity();if (isXiaoMi(getReactApplicationContext())) {height += getNavigationBarHeight(activty);}else {height=0 ;}promise.resolve(height);}/*** 获取底部虚拟按键高度* @param context* @return*/public static int getNavigationBarHeight(Context context) {WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);Display display = windowManager.getDefaultDisplay();DisplayMetrics dm = new DisplayMetrics();try {@SuppressWarnings("rawtypes")Class c = Class.forName("android.view.Display");@SuppressWarnings("unchecked")Method method = c.getMethod("getRealMetrics", DisplayMetrics.class);method.invoke(display, dm);return dm.heightPixels - display.getHeight();} catch (Exception e) {e.printStackTrace();}return 0;}/*** 判断是否是小米手机 并且是否开启全面屏** @return*/public static boolean isXiaoMi(Context context) {if (Build.MANUFACTURER.equals("Xiaomi")) {return Settings.Global.getInt(context.getContentResolver(), "force_fsg_nav_bar", 0) != 0;}return false;}@Overridepublic void initialize() {MainActivity.getActivity().getWindowManager().getDefaultDisplay().getMetrics(metrics);}@Overridepublic boolean canOverrideExistingModule() {return false;}@Overridepublic void onCatalystInstanceDestroy() {}
}
2.编写 Package,在milletAdaptation包下创建MilletAdaptationPackage.java,代码如下:
package com.项目工程名.milletAdaptation;import com.swordsmanapp.milletAdaptation.MilletAdaptation;
import com.facebook.react.ReactPackage;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.uimanager.ViewManager;import java.util.ArrayList;
import java.util.Collections;
import java.util.List;public class MilletAdaptationPackage implements ReactPackage {@Overridepublic List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {return Collections.emptyList();}@Overridepublic List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {List<NativeModule> modules = new ArrayList<>();modules.add(new MilletAdaptation(reactContext));return modules;}
}
3.最后在 Android 这边要做的最后一件事就是注册这个模块,在MainApplication中注册模块:
List<ReactPackage> packages = new PackageList(this).getPackages();// Packages that cannot be autolinked yet can be added manually here, for example:packages.add(new AlipayReactPackage());packages.add(new MilletAdaptationPackage()); // <-- 注册模块return packages;
原生这部分就完成了,在rn端调用:
import {PixelRatio,NativeModules} from 'react-native';componentDidMount() {NativeModules.MilletAdaptation.getHeight().then((height) => {// console.log('height:',height);if(height){this.setState({deviceHeight:height/PixelRatio.get() //当是小米手机并且是全面屏没开按键的情况使用这个高度})}}).catch((err) => {console.log('err:', err);});}
这下是真的完美解决咯,大家如果也遇到这样的困扰,希望可以帮到你们哦~ 在项目的开发过程中,发现小米部分手机有一个全面屏手势功能,该功能可隐藏底部虚拟按键,通过手势的方式来实现返回和Home功能. 效果如下所示: 当开启全面屏手势的时候,就会存在一个问题,我们通过以下代码 ... 小米手机判断当前是不是全面屏状态 public static boolean isFullScreen(Context context) {// true 是手势,默认是 false// https: ... 1 先在laya引擎里设置scaleMode: Laya.stage.scaleMode = Stage.SCALE_EXACTFIT; Laya.stage.screenMode = Stage.S ... 上图为没适配之前 // 在setContentView之后,适配顶部状态栏 getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCE ... React native 安卓机器上调试代码报错:网络请求出错TypeError: Network request failed 安卓机器 usb连接调试 报错信息 TypeError: Networ ... 原标题:华为P40系列将采用鸿蒙和安卓双系统 升降式全面屏 [手机中国新闻]近日,有博主在推特爆料,华为P40系列手机将会有鸿蒙系统和安卓系统两个版本.不出意外的话,应该是以安卓系统版本为主,同时推出 ... Android手机 全面屏(18:9屏幕)适配指南 点击打开链接 从小米MIX 1发布以来,越来越多所谓"全面屏"手机发布,如三星S8,小米MIX2,VIVO X20,Google ... 原标题:跟虚拟导航栏说再见,安卓9.0将使用全面屏手势 [PConline 资讯]昨日,谷歌正式推送了安卓操作系统9.0的大版本更新,别的新功能先不说,有个亮眼的地方就是加入了全面屏手势操作,根据外媒 ... 需求场景:ScrollView中需要一个定高的recyclerView,其高度为屏幕高度,本以为一个简单的需求,调试了半天. 最初的高度获取 public static int getScreenHe ...
步骤写得很清楚,如果有不懂的可以留言,如果觉得有帮助记得给小姐姐点赞哈
react native 安卓(特别是小米手机)全面屏是否开虚拟按键的适配相关推荐
最新文章
热门文章