React-Native 样式、布局、绘制
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了React-Native 样式、布局、绘制相关的知识,希望对你有一定的参考价值。
参考技术A 在web开发中,以往结构、样式、行为的开发通常是分离的,也就是所谓的“关注点分离(separation of concerns)”,它的意思是,各种技术只负责自己的领域(html、css、js),不要混合在一起,形成耦合。HTML 语言:负责网页的结构,又称语义层
CSS 语言:负责网页的样式,又称视觉层
javascript 语言:负责网页的逻辑和交互,又称逻辑层或交互层
这在往日都是好的实践推荐。但是这几年组件化和模块化开发思维渐行其道(特别是React出来后,打破了这一原则,React的基础组织单元是组件,强制要求把html、css、js写在一起),特性或者功能粒度成为一种软件设计和开发上的选择。
那么,在实际开发中,有没有一种超集可以贯穿三者呢? 有,jsx和typescript就是,jsx与typescript是两个不同的概念,但都是一种语法糖,都是JavaScript的超集合,typescript1.6版本是支持jsx的,在react中会用jsx(write css in js、write “html” in js)来开发组件,React-native是react的扩展,在组件开发上也是用的jsx。
component in react-native
在RN中,并不需要学习什么特殊的语法来定义样式,使用JavaScript来写样式。样式名(属性)基本上遵循的是CSS的命名 和规则(比如后定义覆盖原则、样式表现等),只是按照JS的语法要求,某些样式名需要用驼峰命名法(比如css中的background-color 需写成“backgroundColor”)。
样式的定义有两种方式:
内联方法: style=color: red
样式生成器: : styleSheet.creat(textColor: color: red)
在RN中,核心组件都有一个名为style的属性,样式在RN中的应用就是给该属性赋值。属性的值可为JavaScript中的对象({color:red}),或者数组([color: red, color: blue])。
RN中的组件(基础组件、RN中提供的组件)所能应用的样式有一定的范畴,比如color样式不能应用在View组件中。识别哪些组件有哪些可用的样式有两种方法:1,去网上或者官网查。2,调试时打开warn提醒,应用一个样式,如果该组件没有该样式,则会有告警。告警里面会列出该组件所能应用到的样式集合。
在React Native中使用flexbox规则来指定某个组件的子元素的布局。Flexbox可以在不同屏幕尺寸上提供一致的布局结构。RN中的Flexbox规则和Web中Css FlexBox基本一致,主要的不同就是flex-direction默认不同,css中默认是水平方向,rn中默认是垂直方向。具体的flexbox布局相关的知识可以参考我之前写的一篇文章《盒模型与布局》
Web中页面的绘制是浏览器器UI后端做的,而在RN中则是交由原生去绘制(例如ios中的UIkits,具体RN和原生的交互和通讯可以参考我之前写的另外一篇文章《React-Native原理解析与通讯机制阐述(Eg:ios)》),这里只做简单的浅析和对比。
UI Backend就是绘制页面图层的模块。
简单说就是Native初始化 -> 加载JS,JS端注册组件 ->端上调用JS端run方法,传入入口组件名称 -> JS端启动渲染流程。
创建: ReactNative的UI组件通过requireNativeComponent->createReactNativeComponentClass->ReactNativeBaseComponent下mountComponent的调用关系,最终在mountComponent中调用UIManager(Native Module)组件创建View:UIManager.createView(tag, this.viewConfig.uiViewClassName, nativeTopRootTag, updatePayload);,在Native端,UIManager调用对应组件类型的ViewManager(单例,管理类)创建实例。
更新:属性--样式同步,也就是re-render的过程,在这过程中会调用ReactNativeBaseComponent下receiveComponent->UIManager.updateView完成。
参考: https://github.com/facebook/react-native/ http://facebook.github.io/react-native/ http://www.jianshu.com/p/17d6f6c57a5c
react-native 踩坑记
最近在使用react-native的时候遇到了很多坑,这里给大家分享下
一.样式
react-native 虽然支持flex布局,但是所有的样式均是css样式的一个很小的集合,尤其是在安卓机下问题尤为凸显:
1.View内部的元素千万不要超出父级的范围,iso上问题倒是不大,安卓上就什么超出的都看不到了
2.lineHeight 可以用,不过千万不要写成小数,否则安卓上会直接崩溃
3.rn的样式不存在继承的情况,所以基本上每个节点都要写style,真的是体力活
4.如果Text的父级元素设置了背景颜色,那么ios下Text的背景颜色也是父级的背景颜色,要么自己写个Text重置下样式,要么就遇到了再改
5.react-native的字号是没有设置单位的,所以会随着系统设置的字体大小而变化,我也不知道这是不是坑,不过貌似有的app也没有管这个
二.异常
react-native 在发生js异常的时候,debug的时候会直接红屏幕,但是再release的时候直接会崩溃退出,解决办法
import ErrorUtils from "ErrorUtils"
//这里应该做个判断,如果不是debug的才做这样的异常全局处理 ErrorUtils.setGlobalHandler((e)=>{
//发生异常的处理方法,当然如果是打包好的话可能你找都找不到是哪段代码出问题了 Alert.alert("异常",JSON.stringify(e)) });
三.fetch
react-native虽然自带有fetch,不过在使用的时候发现了一个问题,如果需要获取http的header头的时候问题就来了,可能得到的是一些千奇百怪的样式,这并不是react-native的错,而是第三方的 whatwg-fetch 留下的坑,当然也有人再github上跟react-native反映过这个问题,不过得到的解决方案都很坑,唯有一个办法,就是拷贝自己修改,修改如下:
1.注释该注释的
(function(self) { ‘use strict‘; //注释这里,不然总是用的是全局的fetch // if (self.fetch) { // return // }
2.修改该修改的
function parseHeaders(rawHeaders) { var headers = new Headers()
//把\t\n改成\t,因为一般header都是用\n来分割的 rawHeaders.split(‘\n‘).forEach(function(line) { //rawHeaders.split(‘\t\n‘).forEach(function(line) { var parts = line.split(‘:‘) var key = parts.shift().trim() if (key) { var value = parts.join(‘:‘).trim() headers.append(key, value) } }) } return headers }
3.直接import你改好的文件,fetch就可以用了
四.Modal
Mode控件在使用的时候要注意了,因为这个是rn提供的,并且也写的很清楚是最高层级的一个弹出层,所以你想要又打开Model又要跳转基本是无望的了,所以建议不要使用这个,最好是使用第三方的控件,我们用的是 react-native-modalbox + 高阶控件 实现的全遮盖的弹出层
五.点击屏幕其他位置关闭的菜单
这类菜单有个共同的特点就是点击屏幕其他地方然后菜单就关闭,我们的解决办法就是用自己写的 react-native-modalbox + 高阶控件 也就是说放在一个弹出层里面,当然可以试试把当前页面套进一个大的 TouchableWithoutFeedback 里面
暂时就想到了这些,等我好好总结下再写添加吧
以上是关于React-Native 样式、布局、绘制的主要内容,如果未能解决你的问题,请参考以下文章