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);});}

这下是真的完美解决咯,大家如果也遇到这样的困扰,希望可以帮到你们哦~
步骤写得很清楚,如果有不懂的可以留言,如果觉得有帮助记得给小姐姐点赞哈

react native 安卓(特别是小米手机)全面屏是否开虚拟按键的适配相关推荐

  1. Android 小米全面屏手势底部虚拟按键的适配

    在项目的开发过程中,发现小米部分手机有一个全面屏手势功能,该功能可隐藏底部虚拟按键,通过手势的方式来实现返回和Home功能. 效果如下所示: 当开启全面屏手势的时候,就会存在一个问题,我们通过以下代码 ...

  2. 小米手机 全面屏 状态判断

    小米手机判断当前是不是全面屏状态 public static boolean isFullScreen(Context context) {// true 是手势,默认是 false// https: ...

  3. Laya打包的app实现手机全屏 强制关闭虚拟按键

    1 先在laya引擎里设置scaleMode: Laya.stage.scaleMode = Stage.SCALE_EXACTFIT; Laya.stage.screenMode = Stage.S ...

  4. 关于android 7.0全面屏,底部虚拟导航键 适配问题

    上图为没适配之前 // 在setContentView之后,适配顶部状态栏 getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCE ...

  5. android 网络时区 错误,React native 安卓机器上调试代码报错:网络请求出错TypeError: Network request failed...

    React native 安卓机器上调试代码报错:网络请求出错TypeError: Network request failed 安卓机器 usb连接调试 报错信息 TypeError: Networ ...

  6. p40鸿蒙安卓双系统,华为P40系列将采用鸿蒙和安卓双系统 升降式全面屏

    原标题:华为P40系列将采用鸿蒙和安卓双系统 升降式全面屏 [手机中国新闻]近日,有博主在推特爆料,华为P40系列手机将会有鸿蒙系统和安卓系统两个版本.不出意外的话,应该是以安卓系统版本为主,同时推出 ...

  7. Android手机 全面屏(18:9屏幕)适配指南 点击打开链接

    Android手机 全面屏(18:9屏幕)适配指南 点击打开链接 从小米MIX 1发布以来,越来越多所谓"全面屏"手机发布,如三星S8,小米MIX2,VIVO X20,Google ...

  8. Android 9 谷歌全面屏,跟虚拟导航栏说再见,安卓9.0将使用全面屏手势

    原标题:跟虚拟导航栏说再见,安卓9.0将使用全面屏手势 [PConline 资讯]昨日,谷歌正式推送了安卓操作系统9.0的大版本更新,别的新功能先不说,有个亮眼的地方就是加入了全面屏手势操作,根据外媒 ...

  9. 全面屏虚拟按键高度适配

    需求场景:ScrollView中需要一个定高的recyclerView,其高度为屏幕高度,本以为一个简单的需求,调试了半天. 最初的高度获取 public static int getScreenHe ...

最新文章

  1. android蓝牙4.0(BLE)开发之ibeacon初步
  2. 【面经】超硬核面经,已拿蚂蚁金服Offer!!
  3. 让IE7/8使用CSS中first-child和last-child样式属性
  4. Python urllib与requests、XML和HTMLParser
  5. abp框架java,【Net】ABP框架学习之正面硬钢
  6. CF140C-New Year Snowmen【优先队列】
  7. C语言做一个表格的程序,用C语言画个简单表格
  8. 1.C#基础学习笔记3---C#字符串(转义符和内存存储无关)
  9. S19王者荣耀服务器维护,王者荣耀:S19新赛季更新,她没上线惨遭重做,英雄调整,界面优化...
  10. c++值传递和引用及指针传递区别
  11. Android开发之十二:Camera成像原理介绍
  12. java中token什么意思_java中Token验证用法 什么是Token
  13. 汕尾话专用专注微信聊天表情GIF图片
  14. 2021西湖论剑 Re wp
  15. Django批量修改 get_field_display foreignkey
  16. 06【连词】 Conjunction
  17. 线条边框简笔画图片大全_植物简笔画素材大全赶紧收藏起来,一定用的上!
  18. 硬盘柱面损坏怎么办_硬盘在坏道检测中出现了要多少个损坏柱面才说明这个硬盘废了?...
  19. GNU C++ 智能指针6-- 解析_Sp_counted_inplace类
  20. “淘宝” 开放平台接口设计思路

热门文章

  1. 标准差 方差 协方差 相关系数
  2. 微信小程序 | 小鸡单词2.0
  3. 2022电大国家开放大学网上形考任务-教育学非免费(非答案)
  4. Instagram的技术架构
  5. 2021年山东省安全员C证找解析及山东省安全员C证复审考试
  6. [NPUCTF2020]ReadlezPHP与assert函数利用
  7. 使用计算机教学的不足,信息技术在教学中的优势和不足之处
  8. 泰山OFFICE技术讲座:WORD着重号偏离中心的研究
  9. php分页代码简单实现_简单PHP分页
  10. 【项目总结三】:制作简单的SLG城池位置面板