目录
2、Dimension和useWindowDimension
前言
本篇接着前面的RN学习旅程,继续来写RN的学习笔记。
1、alert和console
①、alert
- 功能定位:开发周期常用的调试工具,用于弹出简单信息提示框验证内存对象
- 参数特性:
- 支持任意类型参数传递(字符串/数字/布尔值)
- 传对象时默认显示"object Object",需用JSON.stringify()转换
②、console
- 分级标准:
- console.info():基础信息(深灰色)
- console.debug():调试信息(深灰色)
- console.warn():警告信息(黄色+手机端弹窗)
- console.error():错误信息(红色+手机端弹窗)
- 显示差异:
- info/debug仅在控制台输出
- warn/error会触发设备端可视化提示
- 三种占位符:
- %s(字符串)、%d(数值)、%o(对象),用于在console.log中格式化输出内容
- 与字符串模板区别:占位符方式与ES6字符串模板功能相似,可根据个人偏好选择使用
- 输出组件结构:可以通过console.log(viewLayout)输出组件结构
- 输出表格日志:使用console.table(数组变量)代替常规的console.log输出表格日志
- 输出分组日志:使用console.group()开启分组,console.groupEnd()结束分组,两者之间的日志输出会自动归为一组
2、Dimension和useWindowDimension
①、获取屏幕宽高的两种方式
通过Dimension的get方法
- 基本用法: 调用Dimensions.get('window')获取屏幕宽高信息
- 返回值: 返回包含width和height的对象,如{width: 392.727, height: 813.090}
通过useWindowDimensions Hook
- 在函数组件顶部调用useWindowDimensions() Hook
- 返回值: 同样返回包含width和height的对象
②、获取缩放、文字缩放
const {width,height,scale,fontScale} = Dimensions.get('window');
- scale属性:
- 表示屏幕像素密度比(2.75表示1逻辑像素=2.75物理像素)
- 对应系统设置的"Display size"
- fontScale属性:
- 表示文字缩放比例(1.0为默认值,1.3为最大值)
- 对应系统设置的"Font size"
总结:
|-------------------------|------------------------------------------------|----------------------------------------------|-----------------------------------------|
| dimension API | 获取屏幕分辨率信息(宽高、像素密度等) | get('window') vs get('screen') 高度差异(状态栏是否计入) | 返回对象含 width、height、scale、fontScale |
| useWindowDimension Hook | 通过Hook直接获取屏幕尺寸 | 必须写在组件外层,不可嵌套在函数内 | 返回值与 dimension.get('window') 一致 |
| 屏幕缩放比(scale) | 逻辑像素与物理像素的换算比例(如 2.75) | 与系统字体缩放(fontScale)独立 | scale 固定,fontScale 随系统设置变化(默认 1,最大 1.3) |
| 监听屏幕变化 | dimension.addEventListener('change', callback) | 必须配套 remove 防止内存泄漏 | 回调参数含 window 和 screen 新尺寸 |
| 沉浸式状态栏影响 | 设置沉浸式后 window 与 screen 高度相同 | 非沉浸式时 window.height = screen.height - 状态栏高度 | 需通过 StatusBar API 调整 |
3、Platform获取平台属性
|--------------------|----------------------------|--------------------|
| Platform.OS | 获取当前运行平台(android/iOS/web等) | 移动端主要区分android/iOS |
| Platform.Version | 获取系统SDK版本号(安卓返回API级别) | 版本号对应系统版本关系 |
| Platform.Constants | 获取设备底层参数(品牌/型号/指纹等) | 实际开发中使用频率较低 |
| Platform.isPad | 判断是否为iPad(仅iOS有效) | 安卓返回undefined需特殊处理 |
| Platform.isTV | 判断电视设备(安卓/iOS通用) | TV端开发专用属性 |
| Platform.select() | 跨平台样式适配核心方法 | 对象展开运算符的使用场景 |

4、StyleSheet
①、基础使用
- 创建方法: 使用StyleSheet.create()创建样式表,所有样式属性都写在对象中
- 多属性支持: 可以同时定义多个样式属性
②、创建多个样式表
- 模块化拆分: 将不同模块的样式拆分为独立的样式表(如contentStyles、modalStyles)
- 优势:
- 避免单一文件样式过长难以维护
- 便于代码拆分时直接拷贝整个样式模块
- 实践建议: 按功能模块划分样式表,而非全部集中在组件底部
③、样式合并
- 合并方法: 使用StyleSheet.compose(s1, s2)合并样式
- 与数组写法区别:
- 性能优化: compose返回稳定对象引用,避免数组写法每次渲染创建新数组
- 渲染效率: compose可避免不必要的重绘,数组写法会触发diff算法认为UI需要更新
- 覆盖规则: 后传入样式的同名属性会覆盖前者

④、样式平铺
- 功能: 将多个样式对象合并为一个扁平化样式对象
- 传参方式: 直接传入样式数组StyleSheet.flatten(s1, s2)
- 结果特征:
- 返回单个合并后的样式对象(非数组,合并方法得到的是数组)
- 同名属性后者覆盖前者
- 不同属性直接合并
- 应用场景: 适合组合多种状态控制的样式(如加粗、颜色、下划线等)
⑤、绝对填充
- 本质: position:absolute + 四边距零的快捷写法
- 属性组成: {"bottom":0,"left":0,"position":"absolute","right":0,"top":0}
- 使用方式: 通过StyleSheet.absoluteFill直接引用或展开(...)使用
- 典型应用: 全屏遮罩层、浮动元素等需要充满父容器的场景
⑥、头发丝尺寸
- 定义: 代表设备物理1像素的逻辑尺寸值
- 计算原理: 1像素 = 1 / Dimensions.get('window').scale
- 获取方式: 直接使用StyleSheet.hairlineWidth获取
- 应用场景: 精细边框、分隔线等需要最细线条的场景
5、Linking
①、链接
- openURL:使用Linking.openURL('https://www.baidu.com')可直接跳转系统浏览器打开指定网页
- canOpenURL:在调用openURL前应先使用Linking.canOpenURL()验证URL可打开性
- 地图定位:通过geo:前缀+经纬度格式(如geo:37.2122,12.222)可跳转地图应用定位
- 打电话:使用tel:前缀(如tel:10086)跳转拨号界面
- 发短信:采用sms:前缀(如sms:10086)跳转短信应用
- 发邮件:使用mailto:前缀(如mailto:10086@qq.com)跳转邮件客户端
- 跳转应用:第三方应用(如支付宝/QQ)需在应用底层声明自己的schema,通过Linking.openURL()调用,支持在URL后附加参数,格式为scheme://host?key=value
- openSettings:直接跳转到当前应用的设置页面
- getInitialURL:获取启动应用的深层链接URL
6、PixelRatio:像素比例工具
|-----------------------------|-----------------------------------------------------------------------------------------|---------------------------------------------|----------------------|
| picture radio(像素比例工具) | 用于获取逻辑像素与物理像素的转换比例,API包括:get、getFontScale、getPixelSizeForLayoutSize、roundToNearestPixel | get 返回的值与 Dimensions.get('screen').scale 相同 | 适配不同屏幕密度的布局计算 |
| get() | 返回设备像素密度比(如示例中的 2.625),表示 1逻辑像素=2.625物理像素 | 安卓与iOS返回值逻辑一致 | 基础屏幕适配 |
| getFontScale() | 返回安卓字体缩放比例(默认1),iOS无独立字体缩放,返回值与get()相同 | 仅安卓有效,iOS需注意返回值差异 | 动态字体大小调整 |
| getPixelSizeForLayoutSize() | 输入逻辑像素(如200),返回实际物理像素值(200 * 像素密度比) | 本质是乘法封装,无特殊逻辑 | 精确物理像素计算 |
| roundToNearestPixel() | 解决小数像素导致的布局错位问题(如32.1逻辑像素可能被舍入错误) | 仅需在特殊小数场景使用,非全局必需 | 修复像素舍入导致的UI异常(如背景透出) |
| 与Dimensions的关联 | picture radio.get() ≈ Dimensions.get('screen').scale,但API更简洁 | 优先使用picture radio简化代码 | 屏幕信息获取的替代方案 |
7、BackHandler
BackHandler是专门针对安卓平台的API,用于处理物理返回键事件
- 返回键监听和移除:
- 添加监听:使用BackHandler.addEventListener('hardwareBackPress', callback)在组件加载时注册
- 移除监听:必须配套使用BackHandler.removeEventListener()进行注销,否则会导致内存泄漏
- 回调函数返回true表示消费事件(阻止默认行为),返回false允许事件继续传递
- 退出应用:
- BackHandler.exitApp()可强制退出安卓应用
- 适用于需要跳过页面返回栈直接退出的场景
- Hook简化方案:
- 引入:import { useBackHandler } from '@react-native-community/hooks'
- 使用:useBackHandler(() => { return true/false; })
- 自动处理生命周期,代码量减少70%,底层实现相同,只是封装程度不同
8、PermissionsAndroid
|----------|----------------------------------------------------------|------------------------------------------------------|
| 动态权限机制 | 安卓6.0+将静态权限改为动态权限,需在使用时申请(如拍照、读取文件等) | 静态声明(Manifest)仍必须保留,动态权限是额外要求 |
| 权限检查API | PermissionsAndroid.check() 检查当前是否拥有某权限(返回Promise) | 权限字符串需准确(如android.permission.WRITE_EXTERNAL_STORAGE) |
| 权限申请API | PermissionsAndroid.request() 触发系统弹窗申请权限,返回granted或denied | 弹窗结果需手动处理逻辑(允许/拒绝分支) |
| 多权限申请 | PermissionsAndroid.requestMultiple() 支持批量申请权限数组 | 交互流程与单权限一致,但需注意权限组关联性 |
| 原生桥接替代方案 | 可通过原生代码实现动态权限逻辑,但官方API已封装边界问题 | 需权衡开发效率与定制需求 |
9、Vibration
①、原生声明权限
- 权限类型: 只需在AndroidManifest.xml中声明静态权限android.permission.VIBRATE,无需动态权限申请
- 声明方式: 在<manifest>标签内添加<uses-permission android:name="android.permission.VIBRATE" />
②、发起震动
- 基础调用: Vibration.vibrate()默认产生400毫秒震动
- 安卓定制: 可传入毫秒参数如Vibration.vibrate(1000)实现1秒震动
- 平台差异: iOS不支持自定义时长,单次震动固定为400毫秒
③、取消震动
- API调用: 使用Vibration.cancel()终止所有震动
- 应用场景: 主要配合循环震动模式使用,用于手动停止持续震动
④、安卓时间模式
- 模式语法: 传入数组如100,500,200,500表示"停100ms→震500ms→停200ms→震500ms"
- 执行顺序: 数组奇数位为停顿时间,偶数位为震动时长
- 特点: 安卓支持完全自定义每个阶段的时长
⑤、iOS时间模式
- 模式语法: 数组如100,200,300,400表示"停100ms→震400ms→停200ms→震400ms→..."
- 强制规则: iOS震动时长固定为400ms,数组仅控制停顿间隔
- 平台限制: 无法修改单次震动时长,只能调整停顿时间
⑥、重复震动
- 启用方式: 在时间模式数组后添加true参数,如Vibration.vibrate(100,500,200,500, true)
- 循环机制: 完成整个模式后自动从头开始重复
- 停止方法: 必须显式调用cancel()才能终止循环震动
- 应用场景: 适用于需要持续提醒的场景,如警报、重要通知等
11、ToastAndroid
①、ToastAndroid.show
- 基本语法: ToastAndroid.show(message, duration)
- 参数说明:
- message: 需要显示的字符串内容(如:"这是一个提示")
- duration: 显示时长,可选ToastAndroid.SHORT(3秒)或ToastAndroid.LONG(5秒)
- 使用场景: 适合简单调试场景,比alert更轻量级
②、ToastAndroid.showWithGravity
- 功能说明: 可指定Toast在屏幕中的显示位置
- 参数扩展: 在基础参数上增加gravity参数(如ToastAndroid.TOP/CENTER)
- 实际限制: 由于Android系统限制,在Android 30+版本中位置参数实际不生效,Toast会固定显示在底部
③、ToastAndroid.showWithGravityAndOffset
- 功能扩展: 在指定位置基础上可设置x/y轴偏移量
- 参数格式: showWithGravityAndOffset(message, duration, gravity, xOffset, yOffset)
- 兼容性问题: 与showWithGravity相同,在Android 30+版本中偏移参数不生效
12、transform
通过矩阵变换实现的视觉变形效果,并非真正的3D效果
|-------------|--------------|------------------------------------------|
| transform基础 | 矩阵变换实现的伪3D效果 | 命令式API调用 |
| translate移动 | 二维平面位移控制 | translateX/Y参数设置 坐标系原理(左上角为原点) |
| scale缩放 | 元素尺寸变换 | scale(整体) scaleX/Y(轴向) 1.5倍放大实例 |
| rotate旋转 | 三维空间旋转效果 | rotateX/Y/Z轴向旋转 deg单位使用 默认rotate=rotateZ |
| 复合变换 | 多变换组合效果 | 执行顺序影响结果 矩阵运算不可逆特性 |
| 移动端适配 | 特殊坐标系统处理 | 视口边距计算 overflow隐藏问题 |

13、Keyboard
①、注册键盘监听
- 核心方法:使用Keyboard.addListener()注册监听,需传入事件类型和回调函数
- 关键事件:
- keyboardDidShow:键盘出现时触发(最常用)
- keyboardDidHide:键盘隐藏时触发(最常用)
②、注销键盘监听
- 必要操作:必须调用subscription.remove()注销监听
- 内存风险:未注销会导致内存泄漏和功能异常
- 最佳实践:在useEffect的清理函数中注销
③、隐藏键盘
- 主动隐藏:调用Keyboard.dismiss()可强制隐藏键盘
- 设计原理:
- 没有show()方法是因为键盘出现必须与输入框聚焦绑定
- 原生系统不提供API调出键盘,防止无输入框时误操作
OK,本篇的内容就到这里,下期再会!