React Native 学习之常用组件详解

本贴最后更新于 1979 天前,其中的信息可能已经事过景迁

Text 组件主要用于显示文本;

具有响应性,可以嵌套,可以继承样式

内部 Text 组件可以继承外部 Text 组件的样式

Text 组件的特性:

1.onPress

2.numberOfLines 最多显示多少行

3.onLayout

组件的颗粒度设计主要取决于应用的结构设计

1.头部组件 单独封装 独立成一个文件

module.exports=Header;

const Header=require('./header');

2.列表组件

3.重要新闻 组件

{this.props.news[i]}

警告的处理:数组里面需要 key 属性
参考:https://fb.me/react-warning-keys

2、TextInput 组件

文本输入框:基本组件 自动补全的搜索功能

TextInput 的主要属性和事件如下:

autoCapitalize:枚举类型,可选值有 none sentences words characters 当用户输入时,用于提示

placeholder:占位符,在输入前显示的文本内容

value:文本输入框的默认值

placeholderTextColor:占位符文本的颜色

password:boolean 类型 true 表示密码输入显示*

multiline:多行输入

editable:文本框是否可输入

autoFocus:自动聚焦

clearButtonMode:枚举类型,never while-editing unless-editing always 用于显示清除按钮

maxLength:能够输入的最长字符数

enablesReturnKeyAutomatically:如果为 true 表示没有文本时键盘是不能有返回键的,其默认值为 false

returnKeyType:枚举类型 default go google join next route search send yahoo done emergency-call 表示软键盘返回键显示的字符串

secureTextEntry:隐藏输入内容,默认值为 false

onChangeText:当文本输入框的内容变化时,调用改函数;onChangeText 接收一个文本的参数对象

onChange:当文本变化时,调用该函数

onEndEditing:当结束编辑时,调用改函数

onBlur:失去焦点触发事件

onFocus:获得焦点时触发事件

onSubmitEditing:当结束编辑后,点击键盘的提交按钮触发该事件

3、Touchable 类组件

React Native 没有像 Web 开发那样给元素绑定 click 事件,前面讲的 Text 组件有 onPress 事件回调,View 组件是没有的,但是在实际项目开发中,很多其他的组件也是需要可以被点击的,RN 提供了 3 个组件来赋予被点击的能力(去包裹其他组件即可),这 3 个组件被称为“Touchable 类组件”:

1.TouchableHighlight 高亮

属性:activeOpacity(设置透明度)、onHideUnderlay、onShowUnderlay、underlayColor(点击时背景阴影效果的背景颜色)

2.TouchableOpacity 透明度

属性:activeOpacity

3.TouchableWithoutFeedback 无反馈 不会出现任何视觉变化

不建议使用;属性:onLongPress、onPressIn、onPressOut

在 app 中我们希望点击的时候会有一些视觉上的变化,这个变化会提醒我们已经点击过了,从而避免重复点击

4、Image 组件

React Native 的 Image 组件调用的图片途径比较多:网络图片、本地图片、照相机图片

Image 组件的属性:

resizeMode:图片适用的模式 cover、contain、stretch

source:图片的引用地址

网络图片:source={{uri:'http://.png'}}

本地图片:source={require('./baidulogo.png')}

静态图片资源:注意:如果你添加图片的时候 packager 正在运行,则你需要重启 packager 以便能正确引入新添加的图片。

这样会带来如下的一些好处:

iOS 和 Android 一致的文件系统。
图片和 JS 代码处在相同的文件夹,这样组件就可以包含自己所用的图片而不用单独去设置。
不需要全局命名。你不用再担心图片名字的冲突问题了。
只有实际被用到(即被 require)的图片才会被打包到你的 app。
现在在开发期间,增加和修改图片不需要重新编译了,只要和修改 js 代码一样刷新你的模拟器就可以了。
与访问网络图片相比,Packager 可以得知图片大小了,不需要在代码里再声明一遍尺寸。
现在通过 npm 来分发组件或库可以包含图片了。

注意:为了使新的图片资源机制正常工作,require 中的图片名字必须是一个静态字符串。

#使用混合 App 的图片资源

如果你在编写一个混合 App(一部分 UI 使用 React Native,而另一部分使用平台原生代码),也可以使用已经打包到 App 中的图片资源(通过 Xcode 的 asset 类目或者 Android 的 drawable 文件夹打包)

注意:这一做法并没有任何安全检查。你需要自己确保图片在应用中确实存在,而且还需要指定尺寸

注意:网络图片,你需要手动指定图片的尺寸

关于图片的尺寸,React Native 会自动为你选好。如果没有,则会选择最接近的尺寸进行缩放,但也至少缩放到比所需尺寸大出 50%,以使图片看起来仍然足够清晰。这一切过程都是自动完成的,所以你不用操心自己去完成这些繁琐且易错的代码。

5、ProgressBar 组件

分平台的:ProgressBarAndroid ProgressViewIOS

styleAttr:进度条的样式 Horizontal Small Large Inverse SmallInverse LargeInverse

progress:当前的进度值(在 0 到 1 之间)

6、DrawerLayoutAndroid 组件

封装了平台 DrawerLayout(仅限安卓平台)的 React 组件。抽屉(通常用于导航切换)是通过 renderNavigationView 方法渲染的,并且 DrawerLayoutAndroid 的直接子视图会成为主视图(用于放置你的内容)。导航视图一开始在屏幕上并不可见,不过可以从 drawerPosition 指定的窗口侧面拖拽出来,并且抽屉的宽度可以使用 drawerWidth 属性来指定。

drawerPosition:DrawerLayoutAndroid.positions.Right 左右 默认左

drawerWidth:指定抽屉的宽度,也就是从屏幕边缘拖进的视图的宽度

onDrawerClose

onDrawerOpen

onDrawerSlide:每当导航视图(抽屉)产生交互的时候调用此回调函数

onDrawerStateChanged:idle(空闲) dragging(拖拽中) settling(停靠中)

renderNavigationView:渲染一个可以从屏幕一边拖入的导航视图

drawerLockMode:设置抽屉的锁定模式 有三种模式:

1.unlocked (默认值),意味着此时抽屉可以响应打开和关闭的手势操作

2.locked-closed,意味着此时抽屉将保持关闭,不可用手势打开。

3.locked-open,意味着此时抽屉将保持打开,不可用手势关闭。

无论抽屉处于那种状态,都仍然可以调用 openDrawer/closeDrawer 这两个方法打开和关闭

7、ViewPagerAndroid 组件初探

一个允许在子视图之间左右翻页的容器。每一个 ViewPagerAndroid 的子容器会被视作一个单独的页,并且会被拉伸填满 ViewPagerAndroid。

注意所有的子视图都必须是纯 View,而不能是自定义的复合容器

属性:

1.initialPage 初始选中页的下标

2.onPageScroll 当在页间切换时(不论是由于动画还是由于用户在页间滑动/拖拽)执行

回调参数中的 event.nativeEvent 对象会包含如下数据:
position offset 一个在[0,1)(大于等于 0,小于 1)之间的范围,代表当前页面切换的状态

3.onPageScrollStateChanged idle dragging settling

4.onPageSelected 这个回调会在页面切换完成后(当用户在页面间滑动)调用

回调参数中的 event.nativeEvent 对象会包含如下的字段: position

5.scrollEnabled boolean

8、ListView 组件

原生:mListView mAdapter List 集合数据 MVC

ListView 组件是 React Native 中一个比较核心的组件,用途非常的广。该组件设计用来高效的展示垂直滚动的数据列表。最简单的 API 就是创建一个 ListView.DataSource 对象,同时给该对象传入一个简单的数据集合。并且使用数据源(data source)实例化一个 ListView 组件,定义一个 renderRow 回调方法(该方法的参数是一个数组),该 renderRow 方法会返回一个可渲染的组件(该就是列表的每一行的 item)

由于平台差异性,React Native 中的滚动列表组件 ListView 并没有直接映射为 android 中的 ListView 或 iOS 中的 UITableView,而是在 ScrollView 的基础上使用 JS 做了一次封装。这样,滚动体验部分由 Native 负责,而 React 部分则专注于组件何时渲染、如何渲染等问题。

数据源默认的格式有三个维度:

第一个维度是 sectionId ,标识属于哪一段, 可以手动指定或隐式地使用数组索引或对象的 key 值;
第二个维度是 rowId ,标识某个数据段下的某一个行,同样可以手动指定或隐式地使用数组索引或对象的 key 值;
第三个维度是具体的数据对象,根据实际的需要而定。
需要注意的是,上面只是 默认的数据格式 ,如果它不符合实际的需求, 完全可以使用自定义的数据结构 。唯一的区别就是需要额外指定给 ListView 数据源中哪些是 id,哪些是 rowData。

listview 数据格式

DataSource 的构造函数接收以下 4 个参数(都是可选):
rowHasChanged : 用于在数据变化的时候,计算出变化的部分,在更新时只渲染脏数据;
sectionHeaderHasChanged : 同理,在列表带分段标题时需要实现;
getRowData/getSectionHeaderData : 如果遵循默认的数据源格式,这两个方法就没有必要实现,用内部默认的即可;而当数据源格式是自定义时,需要手动实现这两个方法。

DataSource 的初始化一般在 constructor 方法中

数据源确定后,下一个工作就是列表的渲染。在渲染时发挥重要作用的是 renderRow 属性,它接收数据源中保存的数据对象,并通过返回值确定该行该如何进行展现。我们可以对所有行统一进行展现,也可以根据里面的字段做出不同的展现。在列表包含 sectionHeader 时,还需要实现 renderSectionHeader 方法。

#注意

要更新 datasource 中的数据,请(每次都重新)调用 cloneWithRows 方法(如果用到了 section,则对应 cloneWithRowsAndSections 方法)。数据源中的数据本身是不可修改的,所以请勿直接尝试修改。clone 方法会自动提取新数据并进行逐行对比(使用 rowHasChanged 方法中的策略),这样 ListView 就知道哪些行需要重新渲染了。

#React Native ListView sticky 效果实现

dataBlob{The dataBlob is a data structure (generally an object) that holds all the data powering the ListView}:dataBlob 包含 ListView 所需的所有数据(section header 和 rows),在 ListView 渲染数据时,使用 getSectionData 和 getRowData 来渲染每一行数据。 dataBlob 的 key 值包含 sectionID + rowId

dataBlob

sectionIDs[]:用于标识每组 section

dataBlob

rowIDs[]:用于描述每个 section 里的每行数据的位置及是否需要渲染。在 ListView 渲染时,会先遍历 rowIDs 获取到对应的 dataBlob 数据。
dataBlob

片段头 sticky 失效原因:

1.Found this out by accident, but if you put your ListView inside a ScrollView, the headers will not be sticky

2.iOS RCTScrollView implements sticky headers 而 android 没有

3.ListView 的 Android 版本不支持 sticky-header 特性

4.用这个替代:https://github.com/emilsjolander/StickyScrollViewItems

##分页

当数据量很大的时候如何分页加载 。这种情形分两种情况考虑:

1.数据一次性拿到,边滚动边加载

2.数据不是一次性拿到,而是有可能分屏取数据

对于第一种情况,在 ListView 内部其实已经做了分页的处理:

ListView 内部通过 curRenderedRowsCount 状态保存已渲染的行数;
初始状态下,要加载的数据条数等于 initialListSize (默认为 10 条);
在滚动时检测当前滚动的位置和最底部的距离,如果小于 scrollRenderAheadDistance (默认为 1000),就更新 curRenderedRowsCount ,在它原有值基础上加 pageSize 个(默认为 1 条);
由于属性变化,触发了 ListView 重新的 render 。在渲染过程中, curRenderedRowsCount 起到截断数据的作用,React 的 diff 算法使得只有新加入的数据才会渲染到了界面上。
整个过程类似于 Web 端懒加载机制,即 每次在和底部的距离达到一个阈值时,加载接下来的 pageSize 个数据 。

对于第二种情况,ListView 提供了相关的属性:

onEndReachedThreshold ,在滚动即将到达底部时触发;
onEndReached ,在已经到达底部时触发;

我们可以在这两个方法中调用接口去拿数据,取到数据后再更新数据源。

##滚动

ListView 只是整合了数据和展现,但实际滚动的功能还是由 ScrollView 全权负责。ScrollView 实现完全和平台相关:在 iOS 上,它映射为 RCTScrollView ;在 Android 上,它映射为 RCTScrollView 和 AndroidHorizontalScrollView 。

React Native 让不同端上的技术融合在了一起,同时也给开发人员提出了更高的要求。以 ScrollView 为例,大量的属性其实原封不动映射给了 UIScrollView ,这就意味着如果想再深入地研究下去,必须对客户端相关技术有足够了解。无论是前端还是客户端,跳出自己熟悉的那片领域也许才是更进一步的关键。

谈到滚动,有一点不得不说的就是 列表的无限加载 ,这牵涉到滚动的性能。

Github 上的这个 issue 对此展开了热烈的讨论。其中有人就提到,数据量很大情况下,ListView 在加载时所占用的 CPU 和内存会大大增加,滚动到最后就导致了应用 crash。

为此,ListView 中新添加了一个实验性的属性: removeClippedSubviews ,它能在滚动时及时删掉列表中处于视窗的之外的行,以此达到降低内存消耗的目的。不幸的是,即使设置了这个属性,程序虽然各项占用减少了不少,但还是没避免崩溃的命运。处于好奇,我也在最新版的 ListView 基础上做了简单尝试,不断加载一个无限大的列表,但并没有出现崩溃的情况:

即使加载了 3000、4000 行,Android 真机、iOS 真机和 iOS 模拟器上都没有崩溃;
Android 上明显感到数据加载有 阶段性的延时 ,即滚动一定程度后,再次滚动数据始终加载不出来或要等一段时间才加载出来,体验较差;iOS 相比要流畅的多;
但不崩溃并非最终的目的,很多 React Native 使用者都在试图改进 ListView 的性能表现,相比于直接使用 Native 端的组件,ListView 性能还是差强人意,有很大优化空间。

##总结

ListView 并没有创造出新的东西,它只是集各家所长,很好地将 React 的视图渲染和 Native 端很成熟的滚动机制融合在了一起,使用起来和其他组件无差,静态地定义 View、动态地组织数据,是给人带来的直观感受。

  • React

    React 是 Facebook 开源的一个用于构建 UI 的 JavaScript 库。

    192 引用 • 291 回帖 • 440 关注
  • listview
    1 引用

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...

推荐标签 标签

  • Mac

    Mac 是苹果公司自 1984 年起以“Macintosh”开始开发的个人消费型计算机,如:iMac、Mac mini、Macbook Air、Macbook Pro、Macbook、Mac Pro 等计算机。

    164 引用 • 594 回帖 • 1 关注
  • Spring

    Spring 是一个开源框架,是于 2003 年兴起的一个轻量级的 Java 开发框架,由 Rod Johnson 在其著作《Expert One-On-One J2EE Development and Design》中阐述的部分理念和原型衍生而来。它是为了解决企业应用开发的复杂性而创建的。框架的主要优势之一就是其分层架构,分层架构允许使用者选择使用哪一个组件,同时为 JavaEE 应用程序开发提供集成的框架。

    940 引用 • 1458 回帖 • 160 关注
  • 新人

    让我们欢迎这对新人。哦,不好意思说错了,让我们欢迎这位新人!
    新手上路,请谨慎驾驶!

    51 引用 • 226 回帖
  • FlowUs

    FlowUs.息流 个人及团队的新一代生产力工具。

    让复杂的信息管理更轻松、自由、充满创意。

    1 引用 • 2 关注
  • Swagger

    Swagger 是一款非常流行的 API 开发工具,它遵循 OpenAPI Specification(这是一种通用的、和编程语言无关的 API 描述规范)。Swagger 贯穿整个 API 生命周期,如 API 的设计、编写文档、测试和部署。

    26 引用 • 35 回帖 • 12 关注
  • Openfire

    Openfire 是开源的、基于可拓展通讯和表示协议 (XMPP)、采用 Java 编程语言开发的实时协作服务器。Openfire 的效率很高,单台服务器可支持上万并发用户。

    6 引用 • 7 回帖 • 84 关注
  • 小薇

    小薇是一个用 Java 写的 QQ 聊天机器人 Web 服务,可以用于社群互动。

    由于 Smart QQ 从 2019 年 1 月 1 日起停止服务,所以该项目也已经停止维护了!

    34 引用 • 467 回帖 • 692 关注
  • 前端

    前端技术一般分为前端设计和前端开发,前端设计可以理解为网站的视觉设计,前端开发则是网站的前台代码实现,包括 HTML、CSS 以及 JavaScript 等。

    247 引用 • 1347 回帖
  • 生活

    生活是指人类生存过程中的各项活动的总和,范畴较广,一般指为幸福的意义而存在。生活实际上是对人生的一种诠释。生活包括人类在社会中与自己息息相关的日常活动和心理影射。

    228 引用 • 1450 回帖
  • Sym

    Sym 是一款用 Java 实现的现代化社区(论坛/BBS/社交网络/博客)系统平台。

    下一代的社区系统,为未来而构建

    523 引用 • 4581 回帖 • 692 关注
  • Firefox

    Mozilla Firefox 中文俗称“火狐”(正式缩写为 Fx 或 fx,非正式缩写为 FF),是一个开源的网页浏览器,使用 Gecko 排版引擎,支持多种操作系统,如 Windows、OSX 及 Linux 等。

    7 引用 • 30 回帖 • 455 关注
  • Vue.js

    Vue.js(读音 /vju ː/,类似于 view)是一个构建数据驱动的 Web 界面库。Vue.js 的目标是通过尽可能简单的 API 实现响应的数据绑定和组合的视图组件。

    261 引用 • 662 回帖
  • 阿里巴巴

    阿里巴巴网络技术有限公司(简称:阿里巴巴集团)是以曾担任英语教师的马云为首的 18 人,于 1999 年在中国杭州创立,他们相信互联网能够创造公平的竞争环境,让小企业通过创新与科技扩展业务,并在参与国内或全球市场竞争时处于更有利的位置。

    43 引用 • 221 回帖 • 243 关注
  • frp

    frp 是一个可用于内网穿透的高性能的反向代理应用,支持 TCP、UDP、 HTTP 和 HTTPS 协议。

    15 引用 • 7 回帖 • 9 关注
  • 一些有用的避坑指南。

    69 引用 • 93 回帖
  • Kotlin

    Kotlin 是一种在 Java 虚拟机上运行的静态类型编程语言,由 JetBrains 设计开发并开源。Kotlin 可以编译成 Java 字节码,也可以编译成 JavaScript,方便在没有 JVM 的设备上运行。在 Google I/O 2017 中,Google 宣布 Kotlin 成为 Android 官方开发语言。

    19 引用 • 33 回帖 • 25 关注
  • Elasticsearch

    Elasticsearch 是一个基于 Lucene 的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎,基于 RESTful 接口。Elasticsearch 是用 Java 开发的,并作为 Apache 许可条款下的开放源码发布,是当前流行的企业级搜索引擎。设计用于云计算中,能够达到实时搜索,稳定,可靠,快速,安装使用方便。

    116 引用 • 99 回帖 • 266 关注
  • 大疆创新

    深圳市大疆创新科技有限公司(DJI-Innovations,简称 DJI),成立于 2006 年,是全球领先的无人飞行器控制系统及无人机解决方案的研发和生产商,客户遍布全球 100 多个国家。通过持续的创新,大疆致力于为无人机工业、行业用户以及专业航拍应用提供性能最强、体验最佳的革命性智能飞控产品和解决方案。

    2 引用 • 14 回帖
  • ZooKeeper

    ZooKeeper 是一个分布式的,开放源码的分布式应用程序协调服务,是 Google 的 Chubby 一个开源的实现,是 Hadoop 和 HBase 的重要组件。它是一个为分布式应用提供一致性服务的软件,提供的功能包括:配置维护、域名服务、分布式同步、组服务等。

    59 引用 • 29 回帖 • 15 关注
  • AngularJS

    AngularJS 诞生于 2009 年,由 Misko Hevery 等人创建,后为 Google 所收购。是一款优秀的前端 JS 框架,已经被用于 Google 的多款产品当中。AngularJS 有着诸多特性,最为核心的是:MVC、模块化、自动化双向数据绑定、语义化标签、依赖注入等。2.0 版本后已经改名为 Angular。

    12 引用 • 50 回帖 • 422 关注
  • 百度

    百度(Nasdaq:BIDU)是全球最大的中文搜索引擎、最大的中文网站。2000 年 1 月由李彦宏创立于北京中关村,致力于向人们提供“简单,可依赖”的信息获取方式。“百度”二字源于中国宋朝词人辛弃疾的《青玉案·元夕》词句“众里寻他千百度”,象征着百度对中文信息检索技术的执著追求。

    63 引用 • 785 回帖 • 252 关注
  • 心情

    心是产生任何想法的源泉,心本体会陷入到对自己本体不能理解的状态中,因为心能产生任何想法,不能分出对错,不能分出自己。

    59 引用 • 369 回帖
  • 分享

    有什么新发现就分享给大家吧!

    242 引用 • 1746 回帖 • 1 关注
  • 职场

    找到自己的位置,萌新烦恼少。

    126 引用 • 1699 回帖
  • JRebel

    JRebel 是一款 Java 虚拟机插件,它使得 Java 程序员能在不进行重部署的情况下,即时看到代码的改变对一个应用程序带来的影响。

    26 引用 • 78 回帖 • 620 关注
  • Electron

    Electron 基于 Chromium 和 Node.js,让你可以使用 HTML、CSS 和 JavaScript 构建应用。它是一个由 GitHub 及众多贡献者组成的活跃社区共同维护的开源项目,兼容 Mac、Windows 和 Linux,它构建的应用可在这三个操作系统上面运行。

    15 引用 • 136 回帖 • 9 关注
  • TGIF

    Thank God It's Friday! 感谢老天,总算到星期五啦!

    284 引用 • 4481 回帖 • 656 关注