作者:iplaycodex
仓库:github、codePen
博客:掘金、segmentfault、知乎、简书、博客园
公众号:FEZONE(大写)
分割我:iplaycodex@163.com
特地申明:原创不易,未经受权不得对此文章进行转载或剽窃,否则按侵权解决,如需转载或开明公众号白名单可分割我,尊重原创尊重知识产权从我做起
1. 前言
在应用react-native
进行开发的时候咱们参见官网文档晓得做屏幕适配是应用flexBox
来进行布局.
戳我查看 flexBox 布局
无关flexBox
的属性这里不做太多介绍,不会的请参考官网文档.这里只是说一下在做屏幕适配的时候发现仅仅应用 flexBox
还有点不太够用~
在 react-native
中咱们应用 StyleSheet
这个对象来进行款式的开发.示例代码如下所示:
import { StyleSheet } from "react-native";// 申明了一个style的变量,应用它来给组件增加款式let style = StyleSheet.crate({ title: { fontSize: 14, color: "#BBB", }, subTitle: { marginTop: 10, marginBottom: 10, paddingLeft: 10, paddingRight: 10, },});
能够看到在react-native
中写款式和在web
中写css
还是有很大的区别的.哪些好用的less
,sass
等基本上不能够用.而且也不能够用复合款式
.例如:
web 中写款式
/* web */.title { padding: 10 20 15 5;}
react-native 中写款式
/* react-native */title:{ paddingTop:10, paddingRight:20, paddingBottom:15, paddingLeft:5}
能够看到在rn
中写款式还是有点麻烦~
2. 应用flexbox
布局
flexBox
给咱们提供了很不便的布局办法,然而有时候咱们还是须要一些惯例属性,例如:width
,height
,paddingTop
,fontSize
等等...因为在rn
中款式是没有单位的(默认dp
),那么这个时候问题就来了,在不同的屏幕上它的dpi
是不同的,如何做适配呢?
通过查看官网文档,找到了解决办法.封装了一个办法dp2px
,代码如下所示:
import { Dimensions } from "react-native";const deviceWidthDp = Dimensions.get("window").width;// 默认设计稿375const uiWidthPx = 375;function dp2px(uiElementPx) { return (uiElementPx * deviceWidthDp) / uiWidthPx;}export default dp2px;
这样在开发中如果须要应用一些宽度
,高度
等属性的时候间接援用这个办法就能够了.如下所示:
import dp2px from './dp2px';title:{ paddingTop:dp2px(10), paddingRight:dp2px(20), paddingBottom:dp2px(15), paddingLeft:dp2px(5)}
这样就实现了适配的工作.然而这个就是最优解了么,显然不是.每次写款式的都须要把这个函数援用进来,而且每次都要写大量的dp2xp
,切实是十分的麻烦.那么问题来了,咱们如何优化?
3. 封装 CustomStyleSheet 代替原生 StyleSheet
通过翻看源码,发现StyleSheet
不是一个类,咱们不须要继承它,重写它的这个办法,只须要本人封装一个相似StyleSheet
这样的一个函数在它的外部进行一些计算,而后在须要写款式的中央,对立应用咱们的CustomStyleSheet
代替原生的StyleSheet
即可.代码如下所示:
import { StyleSheet } from "react-native";import dp2px from "./dp2px";let MyStyleSheet = { create(style) { let s = { ...style }; // 目前仅对以下的属性进行解决 let list = [ "width", "height", "marginTop", "marginBottom", "marginLeft", "marginRight", "paddingTop", "paddingRight", "paddingBottom", "paddingLeft", "top", "right", "bottom", "left", "fontSize", "lineHeight", ]; for (outKey in s) { for (innerKey in s[outKey]) { if ( list.includes(innerKey) && typeof s[outKey][innerKey] == "number" ) { s[outKey][innerKey] = px2dp(s[outKey][innerKey]); } } } return StyleSheet.create(s); },};export default MyStyleSheet;
通过上述封装后应用起来就很不便了.在react-native
组件中间接应用它来代替原生的StyleSheet
即可.例如:
import MyStyleSheet from "./myStyleSheet";// 应用封装好的MyStyleSheet来代替原生StyleSheet,间接写数字即可主动转换为不同屏幕适配的dplet style = MyStyleSheet.create({ title: { fontSize: 14, width: 100, }, subTitle: { paddingTop: 10, paddingBottom: 10, marginTop: 10, marginBottom: 10, },});
至此,完结.附上相干材料,供学习
参考资料:
阮一峰的 Flex 教程
4. 结束语
❤️ 关注 + 点赞 + 珍藏 + 评论 + 转发 ❤️
原创不易,激励笔者创作更好的文章~