关于前端:一文解决-ReactNative-屏幕适配的问题

39次阅读

共计 2501 个字符,预计需要花费 7 分钟才能阅读完成。

作者: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;
// 默认设计稿 375
const 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, 间接写数字即可主动转换为不同屏幕适配的 dp
let style = MyStyleSheet.create({
    title: {
        fontSize: 14,
        width: 100,
    },
    subTitle: {
        paddingTop: 10,
        paddingBottom: 10,
        marginTop: 10,
        marginBottom: 10,
    },
});

至此, 完结. 附上相干材料, 供学习

参考资料:

阮一峰的 Flex 教程

4. 结束语

❤️ 关注 + 点赞 + 珍藏 + 评论 + 转发 ❤️
原创不易,激励笔者创作更好的文章~

正文完
 0