chenbin92 / react-native-example Goto Github PK
View Code? Open in Web Editor NEWLearning react native
Learning react native
每个应用程序都希望能有一个吸引眼球,令人难忘的图标,它会出现在用户手机的主屏幕和 App Store上,
所以,设置一个好的 App Icon 会给用户第一眼视觉的享受,是至关重要的。下面的步骤让我们一起来
为你的 App 换上Icon:
Images.xcassets
,点击选中:工欲善其事,必先利其器。整个示例代码都是以Mac OS X系统为基础的;
$ node -v => v5.1.1
$ react-native cli -v => react-native-cli: 0.1.10
=> react-native: 0.20.0
推荐使用 nvm 管理你的 Node.js 版本
$ curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.26.0/install.sh | bash
$ source ~/.nvm/nvm.sh
$ nvm install 5.1.1
$ nvm use 5.1.1
常用 nvm 命令
$ nvm use <version> // 切换版本
$ nvm ls-remote // 查看远程 Node.js 的版本
$ nvm ls // 查看本地安装的 Node.js 的版本
在安装 react-native 之前,需要确保 Node.js 已经安装且在环境变量中;需要确保 Xcode 已经安装且最好是7.1 或者更高版本
$ brew install watchman
$ brew install flow
$ npm install -g react-native-cli // -g 表示全局安装
注:如果安装不成功或者很慢,是因为react-native命令是从npm官网源安装,我们可以改用淘宝镜像源来安装
$ npm config set registry https://registry.npm.taobao.org
$ npm config set disturl https://npm.taobao.org/dist
或者如果你已经安装cnpm:
// 在 /usr/local/lib/node_modules/react-cli/index.js中找到下面一行代码
run('npm install --save react-bative', function(e) {
修改为
run('cnpm install --save react-bative', function(e) {
改用 cnpm 重新安装 react-native-cli,你会发现是如此的快...
$ cnpm install -g react-native-cli // -g 表示全局安装
$ brew -v => Homebrew 0.9.5
$ npm -v => 3.3.12
$ cnpm -b => 3.3.12
$ node -v => v5.1.1
$ nvm --version => 0.17.3
$ react-native cli -v => react-native-cli: 0.1.10
=> react-native: 0.20.0
$ git clone [email protected]:chenbin92/React-native-example.git
$ cd React-native-example
使用 npm
安装项目的依赖: npm
$ npm install
node_modules
- contains the npm packages for the tools we need $ npm start
$ react-native run-ios
ip
地址,如 jsCodeLocation = [NSURL URLWithString:@"http://192.168.1.101:8081/index.ios.bundle"];
commond + D
即可在升级之前,我们可以运行 npm infi react-native
查看react-native的版本信息:
$ npm update -g react-native-cli // 更新本地 react-native-cli的版本
$ npm install --save [email protected] // @后面跟需要升级的版本号
$ react-native upgrade
$ npm install --save [email protected] // @后面跟需要升级的版本号
$ react-native upgrade
React-Native入门指南
React Native: 配置和起步
React Native库版本升级(Upgrading)与降级讲解
去年最火热的技术莫过于 ReactJS 了,各种技术周刊头条。作为一个前端,自然也想尝尝鲜;另一方面,由于所在公司项目的性质,主要是做 hybrid app 开发,技术选型是 angular,ionic,最后是基于 Cordova 去打包。如果涉及到交互性强的应用,这种纯 hybrid 的开发方式自然是会存在一些性能上的问题;那如果开发一些新闻类型的应用,用ionic还是很不错的选择。出于以上两点:不得不去折腾下React Native了。下面的内容出自于2015年11月份在某大学做技术讨论的 PPT (需自备梯子)演讲稿。
2015年移动开发似乎达到了一个新的高度,传统形式的 hybrid app
,基于微信的 h5
单页应用,后起之秀的 react-native
,原生的 Android
,iOS
开发...;技术选型太多,各应用商店 app 的数量更是如雨后春笋,据 ionic 的官网blog介绍,用 ionic 开发的 app 已经超过 60w+ 了,可见移动开发的趋势之火热。
Flexbox
是 React Native 应用开发中必不可少的一部分,也是最常用最基础的内容,下面让我们一起去探索一下什么是flexbox布局:
Flex 是 Flexible Box 的缩写,意为"弹性盒子布局",是 CSS3 新增加的一个布局模块;做过 web 前端开发的人员都清楚,传统的页面布局基于盒状模型,依赖 display属性 + position属性 + float属性。相反的,flexbox 提供了更加灵活的特性,可以简便、完整、响应式地实现各种页面布局。
flexbox布局由伸缩容器和伸缩项目组成。任何一个元素都可以指定为 flexbox 布局,其中设为 display: flex
或 display: inline-flex
的元素称为伸缩容器;
换句通俗的话讲就是:只有设置为 display: flex
或 display: inline-fiex
的元素才能叫做伸缩容器,它的子元素才能使用伸缩布局模型提供的属性来排版。
在讲解伸缩容器属性之前,我们需要先简单了解一下 React Native 提供的基础UI组件,在下面我们会用到这些UI组件结合 flexbox 去布局。
就像学习 HTML 一样,标签十分重要。开发web应用程序时,需要使用很多的 HTML 标签,例如 h1~h6
、p
、ul
、li
等等;但在 React Native中,只提供了基础的UI 组件:
View
: View 组件是一个容器组件,提供了视图布局的功能,是 UI 组件中最基本的组件。它可以多层嵌套,支持flexbox布局,起到容器组件的作用,类似于 web 前端开发中的 div
标签Text
: Text 组件主要用于文本显示,被触摸时可以设置是否高亮与用户响应,支持多层嵌套,所有样式可以继承,Text组件必须被包含在View组件中Image
:ListView
:TextInput
:React Native 将 web 中的flexbox 布局引入进来,使得视图的布局更加简单;目前 React Native 主要支持的 flexbox 属性如下:
flex
: 指定元素是否为伸缩容器flexDirection
: 指定主轴的方向flexWrap
: 指定伸缩容器的主轴方向空间不足的情况下是否换行alignItems
: 定义伸缩项目在伸缩容器的交叉轴上的对其方式justifyContent
: 定义伸缩项目沿主轴线的对其方式alignSelf
: 用来设置单独的伸缩项目在交叉轴上的对其方式flex: number
flexDirection:row | column
flexWrap:wrap | nowrap
alignItems:flex-start | flex-end | center | stretch
justifyContent:flex-start | flex-end | center | space-between | space-around
alignSelf:auto | flex-start | flex-end | center | stretch
下面通过实例演示来实践flexbox布局:
View
和Text
组件的默认宽度<View>
<Text style={{backgroundColor: 'red',height: 100}}> Text 组件默认占据100%的宽度</Text>
<Text style={{backgroundColor: '#469EDD',height: 100}}> Text 组件默认是纵向布局</Text>
</View>
结论: Text 组件默认占据100%的宽度,默认是纵向布局
<View style={{marginTop: 22,flex: 1,flexDirection: 'row', justifyContent: 'flex-start'}}>
<Text style={{backgroundColor: 'red',height: 100}}>1. 父元素必须设置flex属性,才能使用flexbox布局</Text>
<Text style={{backgroundColor: '#469EDD',height: 100}}> 2. flexDirection默认为纵向布局,即主轴默认是竖直方向</Text>
</View>
结论:
flexDirection:row
来改变主轴为水平方向待补充...
用于展示垂直滚动的变化的数据列表
1. 可以指定首次初始化渲染的条数
2. 可以指定每次事件循环渲染的条数
3. 支持下拉刷新(不支持上拉刷新)
1. initialListSize: 初始化渲染的条数,一般大于首屏条数
2. pageSize:每次渲染的条数
3. renderScrollComponent: 返回的组件用来渲染list rows
4. scrollRenderAheadDistance: 顶部屏幕之外的数据离屏幕头部多远时开始渲染数据
5. onEndReachedThreshold: 距离底部多少时出发`onEndReached`
6. dataSource:接受的数据源,`ListViewDataSource`的实例对象,***必须***
7. renderSeparator:每行之间的分割线,函数类型
8. renderRow:每行的渲染函数
9. renderFooter:尾部渲染函数
10. renderHeader:头部渲染函数
11. renderSectionHeader:分组头的渲染函数
12. onChangeVisibleRows:可视化区域变化时出发,屏幕旋转时会调用
13. removeClippedSubviews: 实验性质的属性,提高滚动时到性能,和row的样式‘overflow:hidden’一起使用
通过引用当前listview的实例对象可以调用的方法
1. getMetrics:返回一些常态数据
2. getScrollResponder:返回事件相应器对象
3. setNativeProps:动态设置样式
var dataSource = new ListView.DataSource({
// doSomething
})
var dataSource = new ListView.DataSource({
rowHasChanged: (row1, row2) => row1 !== row2
})
rowHaschanged(): 初始化状态,用于判断状态是否改变,如果 state
改变就重新渲染数据,否则无变化
render: function() {
return (
<ListView dataSource={this.state.dataSource} />
)
}
render: function() {
return (
<ListView
dataSource={this.state.dataSource}
renderRow={(rowData)=> <Text>{rowData}</Text>}
/>
)
}
renderRow(): 接受数组中的每个数据作为参数,返回一个可渲染的组件,作为listview的每一行
var ListViewExample = React.createClass({
// 这里返回一个对象,设置组件的初始化状态,
getInitialState: function() {
var ds = new ListView.DataSource({
rowHasChanged: (r1, r2) => r1 !== r2 // 用于判断当前数据变化的标准
});
return {
dataSource: ds.cloneWithRows(this._genRows()),
};
},
// 生成数据
_genRows: function() {
var dataArray = [];
for(var i=1;i<15;i++) {
dataArray.push("row" + i)
}
return dataArray;
},
render: function() {
return (
<ListView
dataSource={this.state.dataSource} // 数据源
renderRow={(rowData) => <Text style={styles.rowText}>{rowData}</Text>} /> // 接受数组中的每个数据作为参数, 作为listview的每一行(for循环)
);
}
});
var styles = StyleSheet.create({
rowText: {
padding: 18,
borderWidth: 1,
borderColor: '#eee'
},
});
使用 ListView
组件提供的 renderSectionHeader()
方法,我们可以实现一个类似 iPhone 通讯录的滑动效果,如果设置了该方法,会为每一个section渲染一个粘性的header视图。该视图粘性的效果是当刚刚被渲染开始的时候,处于对应的内容的顶部;直到下一个section的header滑动到顶部时,会被替换成当前section的header,以此循环,即是我们常见的类似 iphone 通讯录的滑动效果
先来看看实现的效果图,可以看到底部是常见的一种tab切换效果,有选中效果,自定义的图标(非系统默认提供的图标),可切换不同的视图.
react-native-vector-icons
,提供了3000+的矢量图标3000 Customizable Icons for React Native with support for NavBar/TabBar, image source and full stying.
$ npm install react-native-vector-icons --save
$ rnpm link
在项目根目录下面里执行上面的命令,即可完成 react-native-vector-icons 的安装。
var React = require('react-native');
var {
View,
Text,
TabBarIOS,
} = React;
var Icon = require('react-native-vector-icons/Ionicons');
var TabBarView = React.createClass({
render: function() {
return (
<TabBarIOS>
<Icon.TabBarItem
title="Home"
iconName="ios-home-outline"
selectedIconName="ios-home"
>
<View style={styles.tabContent}><Text>Home Tab</Text></View>
</Icon.TabBarItem>
</TabBarIOS>
);
}
};
这是 react-native-vector-icons
的一个 TabBar 示例代码,我们可以很简单的实现一个单独的 TabBar 效果,主要使用了 TabBarIOS
组件 和 react-native-vector-icons
提供的 Icon.TabBarItem
来完成一个图标和文字组合的 tab 效果。注意在 TabBar 使用图标时需要使用组件默认提供的 Icon.TabBarItem
代替 react-native 提供的 TabBarIOS.Item
,否是会不生效。
TabBarIOS
是 react-native 提供的一个标签栏组件,只适应于 iOS;包含三个属性barTintColor
:标签栏的背景颜色tintColor
:当前被选中的标签图标的颜色translucent
:一个布尔值,决定标签栏是否需要半透明化Icon.TabBarItem
是react-native-vector-icons提供的组件,包含三个属性
iconName
:图标的名称selectedIconName
:选中时图标的名称iconSize
:图标的大小在步骤二中,已经完成了一个底部 TabBarItem 的效果,那接下来继续完成其他三个,并且保证每个 TabBarItem 的内容是相对应的; 这个时候就该 NavigatorIOS 组件出场了,我们修改上面的代码为:
var TabBarView = React.createClass({
render: function() {
return (
<TabBarIOS>
<Icon.TabBarItem
title="Home"
iconName="ios-home-outline"
selectedIconName="ios-home"
>
// 注意这里的改变与步骤二对比
<NavigatorIOS
barTintColor='#5F97F6'
titleTextColor='#fff'
style={styles.navigator}
initialRoute={{
component: ComponentName, // 当前 TabBarItem 需要加载的组件
passProps: {},
title: 'PageTitle',
}}/>
</Icon.TabBarItem>
</TabBarIOS>
);
}
};
initialRoute
属性来提供路由切换功能:在上面 的代码中,component 表示该页面需要加载的视图组件,title 表示需要在头部显示的标题,passProps 用于页面间传递数据。
barTintColor
: 导航条的背景颜色itemWrapperStyle
:为每一项定制样式,例如设置每个页面的背景颜色navigationBarHidden
:当其值为 true 时,隐藏导航栏shadowHidden
:是否隐藏阴影,其值为 true 或者 falsetintColor
: 导航栏上按钮的颜色设置titleTextColor
: 导航栏上的字体的颜色translucent
:一个布尔值,决定标签栏是否需要半透明化initialRoute
:初始化路由。 路由对象如下所示: {
component: function //表示该页面需要加载的视图组件
title: String // 表示需要在头部显示的标题
passProps: object // 用于页面间传递数据
backButtonIcon: // 后退按钮图标
backButtonTitle: // 后退按钮标题
leftButtonIcon: // 左边按钮图标
leftButtonTitle: // 左边按钮标题
onLeftButtonPress: // 左边按钮点击事件
rightButtonIcon: // 右边按钮图标
rightButtonTitle: // 右边按钮标题
onRightButtonPress: // 右边按钮点击事件
wrapperStyle: // 包裹样式
}
在步骤三中,讲解了 NavigatorIOS 组件的使用,实现了标签栏的 TabBar 切换效果,可以切换 TabBarItem 加载不同的 component;接下来,我们需要让 TabBarItem 对应的视图可以通过路由链接到其他页面,代码如下:
_navigateToSubview: function() {
this.props.navigator.push({ // 调用navigator对象的push()方法
component: MessageDetail,
title: "Detail",
rightButtonTitle: 'New',
onRightButtonPress: function(){
alert('On right button press!');
}
})
}
在组件切换时, navigator 会作为一个熟悉对象被传递。 我们可以通过 this.prpps.navigator
获得 navigator 对象。它可以控制路由的跳转和组件的加载。
* push(route): 加载一个新的页面(视图或者路由)并且路由到该页面
* pop(): 返回到上一个页面
* popN(n): 一次性返回N个页面,当 N = 1时, 即相当于pop()方法的效果
* replace(route): 替换当前的路由
* replacePrevious(route): 替换前一个页面的视图并且回退过去
* resetTo(route): 取代最顶层的路由并且回退过去
* popToTop(): 回到最上层视图
先来看看下面实现的效果图,你会发现这是一个常见的应用程序启动时的滑动介绍效果(LandingPage),以及滑动完成时出现注册登录按钮,引导用户注册登录,之后进入应用程序的首页,现在许多流行的应用程序如 知乎
、支付宝
、叮叮
等都有类似的功能
react-native-swiper
react-native-swiper 是一款轮播组件,封装了不同风格的轮播效果,我们只需要使用 npm 来安装即可:
$ i react-native-swiper --save
安装成功后,需要确保组件能够正常使用,简单示例代码如下:
var Swiper = require('react-native-swiper')
var swiper = React.createClass({
render: function() {
return (
<Swiper style={styles.wrapper} showsButtons={true}>
<View style={styles.slide1}>
<Text style={styles.text}>第一张</Text>
</View>
<View style={styles.slide2}>
<Text style={styles.text}>第二张</Text>
</View>
<View style={styles.slide3}>
<Text style={styles.text}>第三张</Text>
</View>
</Swiper>
)
}
})
在 Swiper 组件中提供了很多的属性,可以根据需求高度化的定制 Swiper,具体请查看文档
观察上面的示例动画,我们可以发现 Swiper 的最后一页是会出现注册登录按钮,点击按钮会路由到详细的登录页面,我们先来实现简单的登录页面视图,暂时不考虑表单验证以及数据交换,我们会在后面详细去设计我们的表单;主要代码如下所示:
var Login = React.createClass({
render: function() {
return (
<View style={styles.loginContainer}>
<Image
style={styles.logoImage}
source={{uri: 'http://7xr387.com1.z0.glb.clouddn.com/logo2.png'}} />
<TextInput
style={styles.accountInput}
placeholder='Phone Number' />
<View style={{height:1,backgroundColor:'#f4f4f4'}} />
<TextInput
style={styles.passowrdInput}
placeholder='Passowrd'
password={true} />
<View style={styles.loginButton}>
<Text style={{color: '#fff'}} >Login</Text>
</View>
<View style={{flex:1,flexDirection:'row',alignItems: 'flex-end',bottom:10}}>
<Text style={styles.viewUnlogin}>
无法登录?
</Text>
<Text style={styles.viewRegister}>
新用户
</Text>
</View>
</View>
)
}
})
上面我们准备好了 Swiper
和 Login
组件,以及上一篇文章实现的 TabBar
,下面我们看看如果将它链接起来:
这里我们主要使用了react-native 提供的 navigator
组件和 navigatorIOS
组件来完成由 LandingPage component——> Login component ——> TabBar component 的一个路由过程:
// from landingSwiper to login
<Navigator
initialRoute = {{name:"landingSwiper", component: LandingSwiper}}
renderScene={(route, navigator) => {
let Component = route.component;
return <Component {...route.params} navigator={navigator} />
}} />
// from login to TabBar
_login: function() {
this.props.navigator.resetTo({
component: TabBar,
title: 'Home',
})
},
NavigatorIOS 不能出现多层嵌套,否则会出现以下错误,解决方案详见
Invariant Violation: No navigator item should be pushed without JS knowing about it 1 0"
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.