2017-09-09 15:24:43

React Native:HTML转View漫谈

RN解决了安卓和IOS之间一部分的复用问题,但官方一点也没有提及到复用WEB端的HTML,即通常所说的HTML转View(View是RN的基本视图单位,类比于HTML的div)。本文介绍一下博主在RN复用HTML这方面的探索。

HTML转View目前的可行性

如果RN能够自动将一个HTML页面转码成Native控件,那该多强大啊!然而很可惜,这个想法和画个图片再让它自动导出直接可上线的HTML页面一样,属于目前为止100%不可能的东西。这两者的原因都很类似,博主简单列举几点:

不对称的布局

二维软件中制作好的图片,内容全部都是绝对布局,因此导出成响应式HTML是不可能的,毕竟图片中的信息不包括响应式,巧妇难为无米之炊。而如果想自动地根据图片信息生成响应式HTML,那么flex布局、table布局、XXX布局那么多种布局该选哪一种?每种布局里的那么多的变量又有多少是一张图片的信息能够决定的呢?

和图片转HTML的情形正好相反,HTML转View的时候,HTML布局系统太多,RN反而只有一个flex布局,因此样式是没有办法成功复制HTML的。另外,即使是只有一个flex布局,它的bug仍然很多(比如TouchableNativeFeedback涟漪错位),更别说实现其他布局系统了。

不对称的组件

RN连安卓和IOS之间的组件都没有做到90%复用,那当然更别说HTML中标签对应的组件了。举个简单的栗子🌰,video对应的RN官方组件干脆不存在,更别说flash了,RN的webview都干脆跑都跑不起来,更多的可以直接查询react-native-web的组件库了。

不对称的样式

可以说每一个网页中都有HTML的样式继承,然而RN的全部都是内联样式,继承什么的不存在。这导致我们需要一一书写样式继承对应的内联样式

HTML转View的现状

既然一整版HTML转View是不大可能了,那么可以转一小部分HTML么?答案是可以的,目前常用的一个库是react-native-htmlview,封装地还算不错,但是仍然有一些比较大的问题,导致它连稍微大一点的HTML都解析不了,因此,有不少人尝试fork它并做了自己的修改,其中当然包括我写的psnine中使用的版本,接下来主要介绍一下博主遇到的一些问题和做得一些工作。

安卓Text控件不允许内嵌View

这个问题十分严重,因为文字中内联标签是一个太正常不过的WEB端表现形式了,更加尴尬的是RN的安卓不行但是iOS却可以内嵌View。

即使iOS可以在Text中内嵌View,也需要预先设定View的高度,因此需要制定一个相同的策略,在本来该嵌套在Text中的组件全部提升到顶层View中,以避免内容消失的问题。

Text控件的样式继承

RN的组件全部都是内联样式,因此将HTML转为View时,需要向上递归查找class和style的值,并将它们过滤后映射为合法的RN样式。更好的办法是递归进入时就传入父标签的样式,不过本文这种转换的性能瓶颈根本在这一块,所以无伤大雅。

色彩

幸运的是,在色彩方面React Native与Web差别不大,都支持具名颜色、rgb、rgba、hex、短hex等色彩字符串,因此转换比安卓上容易多了。

结果

实际效果可以参考我写的安卓端psnine的任意帖子,里面的主题内容和评论内容全部是直接将HTML作为唯一参数用一个组件渲染出来的,从安卓端来看效果是不错的。iOS端由于本身屏幕比安卓要小,因此布局看起来会乱得多。

本文链接:https://smallpath.me/post/react-native-html-to-view

-- EOF --