知识点:
- 给首页添加 Banner
- 给首页添加运营模板
- 获取接口的商品
- 给顶部加一个搜索条
从这篇开始正式案例的开发,Git 仓库的地址会放到下一篇中显示,需要的读者可以直接去 Git 上看每一次提交的代码。
本文先从最早的代码形式开始一步一步的讲下去,开始开发的 App 会在某些情况下很卡,后面会将优化需要做的东西讲出来,这里先从简单的实现 App 界面开始讲,如果觉得手机反应慢,请看后面的优化部分内容。
首页容器
修改首页 index.js 文件,创建一个容器,用来放置后面要添加的各种组件。
Banner 和快捷入口
这里的 Banner 用到了一个轮播图组件,根目录下执行npm i --save react-native-swiper
安装新的组件。
创建一个组件,该组件用来放 Banner 和快捷入口。
这里创建 state 中变量,banners 用来存储 banner 列表,quicks 用来存储快捷入口的列表。
请求远程接口,将返回的数据放入 state 中。
将 banner 渲染再页面上,这里有一个小技巧,如果只有一张图片就不再使用轮播图。
接下来就是快捷入口,由于快捷入口用到了 Gif 图,所以这里添加一个第三方的组件react-native-fast-image
。在线的项目使用的是官方推荐的设置方法,让 RN 的 image 组件支持的 Gif。
执行npm i --save react-native-fast-image
,然后使用 link 命令将组件加入到原生代码里,react-native link react-native-fast-image
,执行完毕重新运行模拟器react-native run-ios
。
将 state 中的数据渲染在 banner 的下面,这里用到了几个组件和一个新的图片,需要单独添加。ImageBackground 是 RN 在 0.47 之后的版本加入的组件,它可以将一个图片当做背景来使用,这里推荐在 0.50 之后的版本中使用。
刷新模拟器看看效果,一个简单的 banner + 入口的界面就显示出来了,是不是非常简单!
自定义模板
从入口下面开始就是一个自定义的模板,这里使用现成的接口,现成的设计来做模板。运营人员会在后端传入图片并设置跳转链接,App 根据设计好的样式渲染模板结果,目前有 8 个模板在使用,后面可能会添加更多,这里先不管后面的新模板。
在 home 下新建一个floor_modules.js
文件,自定义模板单独放在这里处理,由于代码比较长就不贴出来了,有想看具体情况的可以去 Git 仓库看。
到目前为止使用还是 View 组件,该组件是不支持滑动的,要想列表可以滑动,需要将渲染结果放在专门的列表组件中才行。这里不适用 ScrollView 的原因是,FlatList 可以在滚动的时候隐藏屏幕外的无用节点,可以提高列表性能,尤其是列表非常长的时候。
把刚才写的两个组件放到 Flatlist 中的 header 组件中 ListHeaderComponent。
- 使用 numColumns 设置列表为双列。
- 使用 refreshing 传入下拉刷新使用到的变量。
- 使用 onRefresh 在下拉刷新的时候重新获取列表数据。
- 使用 onEndReached 在滑动到列表底部的时候加载下一页。
- 使用 ListHeaderComponent 渲染列表的头。
- 使用 renderItem 渲染列表项。
- 使用 ListFooterComponent 设置底部的文字,一般可以给加载下一页展示加载的状态、文字。
- 使用 onScroll 在滑动的时候触发自己的事件,这里使用 scrollEventThrottle 控制触发的频率,内部的数字就是 1000 毫秒内触发的次数,数字越大触发越少。
- 使用 keyExtractor 设置列表每个项的 key,在列表判断列表项的时候会使用这个返回的 ID 作为 key。注意,这里返回的值不能重复。
- 使用 data 设置商品的项,必须是数组。
商品列表
首先给上面的两个组件添加一个名字,然后在刷新方法里调用他们的刷新方法,这样就可以做到在下拉刷新的时候同时可以刷新前面两个组件。
添加一个请求数据的方法并在组件初始化结束之后调用方法,这里使用 await 来达到同步等待请求结果的效果。注意,必须使用 try 来包裹这个方法,否则在返回错误信息的时候会发生 App 奔溃的效果。
这里设置了一个 start 变量来存储页码。需注意,只有需要改变 UI 的变量才需要放到 state 里面,其他的尽量放到组件自身上面或者其他地方,否则在改变一些无意义的数据的时候也会触发界面刷新。
这里把加载下一页单独写成一个方法了,有的手机在初始化列表的时候不仅会调用一次获取第一页的方法,同时也会调用一次下一页的方法。
新建商品列表组件 GoodItem,修改 Flatlist 组件,把 GoodItem 放到内容渲染方法里。
这里将数组序号也传入组件,目的是给商品列表的每一项添加一个不一样的样式,这里设置的样式在 Android 和 iOS 上会有不同的效果:
通过取余方法即可完成每行有两种不同的样式,这在双列的列表中非常的常用。
首页列表中的这个大块头部组件和列表中的非常多得商品项会暴露出很多问题,后面会把这一块优化,以达到和原生一样的效果。
头部组件
初步开发已经完成了,但是还需要在这个的基础上再加上头部组件,这个组件负责显示用的一些信息和一个假的搜索条。这样才是一个完整的 App 该有的样子。
添加一个 SearchHeader 组件,用来做商品列表页的顶部。
//顶部搜索条组件
class SearchHeader extends React.Component{
render(){
//这里先不去管具体的内容
return <View></View>
}
}
将组件放在最外层,同时使用绝对定位将顶部浮动在所有组件的最前面。这里先不讲动画,看着难受的读者可以先把浮动的组件改成普通的组件。
const styles = StyleSheet.create({
headerView: {
position: "absolute",
left: 0,
right: 0,
top: 0,
zIndex: 100,
},
pageView: {
flex: 1,
width: deviceWidth,
},
loading: {
textAlign: 'center',
fontSize: px(28),
color: "#ccc"
},
})
顶部添加一个头像显示组件,中间添加一个输入框,该输入框没有实际的功能,主要是为了跳转到真正的搜索页的。
到这里基本就开发完了,将它们组合在一起然后刷新页面。
完成
到这里就完成了基础的首页开发,一个简单的首页就呈现在外面的面前。如果懂打包的读者已经可以马上打一个 APK 文件了。这里稍微注意一下,模拟器使用的是 iOS,打包最方便的还是 Android,但是 iOS 和 Android 在某些情况下会有一些区别,比如样式上会根据手机的不同有一些不一样的效果,有些组件甚至只支持 iOS。
在浏览的时候也会看到滑动会有一些生涩,点击跳转也没有做,顶部最好有一些动画等等,这些在后面都会有涉及。
图中就是在说列表太长导致更新很慢,同时还提醒开发者使用 PureComponent 来优化性能,后面将介绍怎样使用 purComponent 和 shouldComponentUpdate 来优化性能。