先看democss
从开始学RN到如今大概有2个星期天左右了,这里先记录一下,也算个小阶段总结。就目前感受,RN的优点和劣势都很明显;html
官网说的很详细,按照官网的步骤基本没问题,就很少赘述前端
官网地址: reactnative.cn/docs/gettin…node
建立Q项目,并用iOS模拟器运行起来react
react-native init q
cd q
react-native run-ios
复制代码
项目内容以下:android
先看index.js
, import
是引入文件,AppRegistry.registerComponent(appName, () => App);
整个的意思就是将工程目录的App.js
注册成组件并引入,因此一开始显示的即App.js
里面的内容ios
import {AppRegistry} from 'react-native';
import App from './App';
import {name as appName} from './app.json';
AppRegistry.registerComponent(appName, () => App);
复制代码
App.js
文件里面大体能够分红三部分web
有过前端开发经验的朋友对View
,Text
,ScrollView
这些并不陌生,在React-native中,全部组件都要单独引入,全部组件及做用可看官方文档npm
import React from 'react';
import {
SafeAreaView,
StyleSheet,
ScrollView,
View,
Text,
StatusBar,
} from 'react-native';
import {
Header,
LearnMoreLinks,
Colors,
DebugInstructions,
ReloadInstructions,
} from 'react-native/Libraries/NewAppScreen';
复制代码
这里部份内容是画UI,基本上和html
没差多少,都是用各类组件的堆砌。学过web或者小程序之类的看起来会很简单,没学过的话,建议选去学学最基本的html + css
json
const App: () => React$Node = () => {
return (
<StatusBar barStyle="dark-content" />
<SafeAreaView>
<ScrollView
.....
.....
</SafeAreaView>
</>
);
};
export default App;
复制代码
这里是各类样式,大部分都是沿用css
的,看到这里大概感受到React-native其实就是前段代码换个壳,对于有前段知识的人学起来应该会很轻松,没有相关知识的话建议仍是先去学学基础的再来搞React-native
const styles = StyleSheet.create({
scrollView: {
backgroundColor: Colors.lighter,
},
.....
.....
});
复制代码
有这些了解后,能够试着作一个简单的列表页面
1.导入组件,须要的组件大概有这些,重点是FlatList
列表组件
import React, { Component } from "react";
import { Image, FlatList, StyleSheet, Text, View } from "react-native";
复制代码
2.导出默认类App扩展组件,包括住下面的其余代码
export default class App extends Component {
}
复制代码
3.建立个长度是8的data数组,后面可给FlatList
赋值用
constructor(props) {
super(props);
this.state = {
data: [{}, {}, {}, {}, {}, {}, {}, {}],
};
}
复制代码
4.RN的render()函数实际上跟iOS的ViewDidLoad()函数类似,返回的就是具体的内容,内容很固定,只能是一个组件,这里我返回的是FlatList
,字段说明以下
renderMovie
渲染render() {
return (
<FlatList
data={this.state.data}
style={styles.list}
renderItem={this.renderMovie.bind(this)}
keyExtractor={item => item.id}
/>
);
}
复制代码
5.经过renderMovie
函数返回item的内容,这里能够任意发挥
renderMovie({ item }) {
return (
<View style={styles.container}>
<Image
source={{ uri: 'https://gss3.bdstatic.com/7Po3dSag_xI4khGkpoWK1HF6hhy/baike/w%3D268%3Bg%3D0/sign=e4d6ea2325dda3cc0be4bf2639d25e3c/b64543a98226cffcb1f7cc0eb2014a90f703eaa9.jpg' }}
style={styles.thumbnail}
/>
<View style={styles.rightContainer}>
<View style={styles.titleWithout}>
<Text style={styles.title}>罗小黑战记</Text>
<Text style={styles.tip}>中国巨屏</Text>
</View>
<Text style={styles.score}>猫眼评分<Text style={styles.grade}> 9.8 </Text></Text>
<Text style={styles.starring}>主演:罗小黑,罗小白</Text>
<Text style={styles.cinema}>今天129加音乐反映124场</Text>
</View>
<Text style={styles.buy}>购买</Text>
</View>
);
}
复制代码
6.最后是样式,其实这些随意发挥便可
这样简单的一个页面就完成了,完整代码以下,能够直接copy替代原有内容运行便可看到效果
import React, { Component } from "react";
import { Image, FlatList, StyleSheet, Text, View, TouchableOpacity } from "react-native";
export default class App extends Component {
constructor(props) {
super(props);
this.state = {
data: [{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {},],
};
}
render() {
return (
<FlatList
data={this.state.data}
style={styles.list}
renderItem={this.renderMovie.bind(this)}
keyExtractor={item => item.id}
/>
);
}
renderMovie({ item }) {
return (
<View style={styles.container}>
<Image
source={{ uri: 'https://gss3.bdstatic.com/7Po3dSag_xI4khGkpoWK1HF6hhy/baike/w%3D268%3Bg%3D0/sign=e4d6ea2325dda3cc0be4bf2639d25e3c/b64543a98226cffcb1f7cc0eb2014a90f703eaa9.jpg' }}
style={styles.thumbnail}
/>
<View style={styles.rightContainer}>
<View style={styles.titleWithout}>
<Text style={styles.title}>罗小黑战记</Text>
<Text style={styles.tip}>中国巨屏</Text>
</View>
<Text style={styles.score}>猫眼评分<Text style={styles.grade}> 9.8 </Text></Text>
<Text style={styles.starring}>主演:罗小黑,罗小白</Text>
<Text style={styles.cinema}>今天129加音乐反映124场</Text>
</View>
<Text style={styles.buy}>购买</Text>
</View>
);
}
}
var styles = StyleSheet.create({
container: {
flex: 1,
flexDirection: "row",
justifyContent: "center",
alignItems: "center",
backgroundColor: "#fff"
},
header: {
height: 20,
marginTop: 44,
},
rightContainer: {
flex: 1,
paddingLeft: 18,
},
titleWithout: {
flexDirection: "row",
fontWeight: "bold",
alignItems: "center",
},
title: {
fontSize: 14,
marginTop: 4,
lineHeight: 0,
},
tip: {
backgroundColor: "#999",
fontSize: 8,
textAlign: "center",
color: "#fff",
height: 14,
width: 40,
lineHeight: 14,
borderRadius: 2,
marginLeft: 4,
marginTop: 4,
},
score: {
paddingTop: 8,
fontSize: 12,
color: "#666",
},
starring: {
paddingTop: 4,
fontSize: 12,
color: "#666",
},
cinema: {
paddingTop: 4,
fontSize: 12,
color: "#666",
},
buy: {
fontSize: 12,
// color:'#333',
width: 46,
height: 24,
lineHeight: 24,
textAlign: "center",
backgroundColor: "#D44145",
color: "#fff",
borderRadius: 12,
marginRight: 20,
},
grade: {
color: "#DF8D7A",
},
year: {
textAlign: "center"
},
thumbnail: {
width: 68,
height: 94,
marginLeft: 20,
marginTop: 10,
marginBottom: 10,
},
list: {
paddingTop:40,
backgroundColor: "#F5FCFF"
},
headerOutline: {
backgroundColor: "#fff",
marginTop: 44,
},
headerInside: {
backgroundColor: "#f5f5f5",
flexDirection: "row",
justifyContent: 'space-between',
marginLeft: 20,
marginRight: 20,
marginBottom: 6,
paddingTop: 10,
paddingBottom: 4,
paddingLeft: 10,
paddingRight: 10,
},
trendIcon: {
width: 10,
height: 14,
marginLeft: 10,
marginTop: -1,
},
trendText: {
height: 22,
color: '#333',
fontWeight: "bold",
},
trendR: {
color: '#333',
fontSize: 10,
fontWeight: "bold",
height: 22,
},
trendRText: {
},
trendMoney: {
color: '#D24349',
},
});
复制代码
二 Navigation与Tabbar
如图,最终目的是建立一个带Navigation
,Tabbar
的demo,可分为三个步骤
index.js
入口注:这里有个天坑,react-navigation4与3差距很大,如今网上的教程基本使用的都是react-navigation 3,这里我也是兜兜转转搞了许久才意识到的,你们都是初学者,建议安装版本3
yarn add react-navigation@3.5.1
yarn add react-native-gesture-handler
复制代码
这里可能会报这个错
Error: Requiring unknown module "447". If you are sure the module exists, try restarting Metro. You may also want to run `yarn` or `npm install`.
复制代码
这个错缘由不少,能够尝试
npm install
react-native run-ios
复制代码
或者
cd ios
pod install
cd ..
react-native run-ios
复制代码
detailsScreen.js
,settingScreen.js
,navigation.js
文件detailsScreen.js
内容
import React from 'react';
import {
View,
Text,
Button,
Image,
} from 'react-native';
export default class detailsScreen extends React.Component {
render() {
return (
<View style={{flex:1, alignItems:'center',justifyContent: 'center'}}><Text>详情页</Text></View>
);
}
}
复制代码
settingScreen.js
内容
import React from 'react';
import {
View,
Text,
Button,
Image,
} from 'react-native';
export default class settingScreen extends React.Component {
render() {
return (
<View style={{flex:1, alignItems:'center',justifyContent: 'center'}}><Text>设置页</Text></View>
);
}
}
复制代码
navigation.js
内容须要分步讲解一下,首先引入全部须要的组件与页面
import React from 'react';
import { Text } from 'react-native'
import HomeScreen from "./App";
import DetailsScreen from "./detailScreen";
import SettingScreen from "./settingScreen";
import {
createStackNavigator,
createAppContainer,
createBottomTabNavigator
} from 'react-navigation';
复制代码
这里是声明HomeStack
,SettingsStack
两个组件;
createStackNavigator 提供APP屏幕之间切换的能力,它是以栈的形式还管理屏幕之间的切换,新切换到的屏幕会放在栈的顶部。
const HomeStack = createStackNavigator({
Home: { screen: HomeScreen, }
})
const SettingsStack = createStackNavigator({
Settings: { screen: SettingScreen },
})
复制代码
这里声明TabNavigator
createBottomTabNavigator(RouteConfigs, BottomTabNavigatorConfig)至关于iOS里面的TabBarController,屏幕下方的标签栏
const TabNavigator = createBottomTabNavigator(
{
Home: { screen: HomeStack },
Settings: { screen: SettingsStack }
},
{
navigationOptions: () => ({
header: null
}),
defaultNavigationOptions: ({ navigation }) => ({
tabBarLabel: ({ tintColor}) => {
const { routeName } = navigation.state
switch (routeName) {
case 'Home':
return <Text style={{ color: tintColor, fontSize: 12 }}>{'首页'}</Text>
case 'Settings':
return <Text style={{ color: tintColor, fontSize: 12 }}>{'设置'}</Text>
}
},
tabBarIcon: ({ focused, tintColor }) => {
let urld
const { routeName } = navigation.state
switch (routeName) {
case 'Home':
return <Image source={{ uri: 'https://static.easyicon.net/preview/119/1191814.gif' }} style={[{height: 20, width: 20}]}/>
case 'Settings':
return <Image source={{ uri: 'https://static.easyicon.net/preview/121/1215319.gif' }} style={[{height: 20, width: 20}]}/>
}
}
}),
tabBarOptions: {
inactiveTintColor: 'gray',
}
}
)
复制代码
最后设置路由并返回
const AppStack = createStackNavigator({
Tabs: TabNavigator,
Details: { screen: DetailsScreen },
}, {
defaultNavigationOptions: () => ({
})
})
export default createAppContainer(AppStack)
复制代码
完整代码以下
import React from 'react';
import { Text,Image} from 'react-native'
import HomeScreen from "./App";
import DetailsScreen from "./detailScreen";
import SettingScreen from "./settingScreen";
import {
createStackNavigator,
createAppContainer,
createBottomTabNavigator
} from 'react-navigation';
const HomeStack = createStackNavigator({
Home: { screen: HomeScreen, }
})
const SettingsStack = createStackNavigator({
Settings: { screen: SettingScreen },
})
const TabNavigator = createBottomTabNavigator(
{
Home: { screen: HomeStack },
Settings: { screen: SettingsStack }
},
{
navigationOptions: () => ({
header: null
}),
defaultNavigationOptions: ({ navigation }) => ({
tabBarLabel: ({ tintColor}) => {
const { routeName } = navigation.state
switch (routeName) {
case 'Home':
return <Text style={{ color: tintColor, fontSize: 12 }}>{'首页'}</Text>
case 'Settings':
return <Text style={{ color: tintColor, fontSize: 12 }}>{'设置'}</Text>
}
},
tabBarIcon: ({ focused, tintColor }) => {
let urld
const { routeName } = navigation.state
switch (routeName) {
case 'Home':
return <Image source={{ uri: 'https://static.easyicon.net/preview/119/1191814.gif' }} style={[{height: 20, width: 20}]}/>
case 'Settings':
return <Image source={{ uri: 'https://static.easyicon.net/preview/121/1215319.gif' }} style={[{height: 20, width: 20}]}/>
}
}
}),
tabBarOptions: {
inactiveTintColor: 'gray',
}
}
)
const AppStack = createStackNavigator({
Tabs: TabNavigator,
Details:DetailsScreen,
}, {
defaultNavigationOptions: () => ({
})
})
export default createAppContainer(AppStack)
复制代码
index.js
入口这里仅仅只是把入口改成navigation.js
import {AppRegistry} from 'react-native';
import Nav from './navigation.js';
import {name as appName} from './app.json';
AppRegistry.registerComponent(appName, () => Nav);
复制代码
保存基本就能看到App的架子大概造成了
接下来要设置一下点击事件,让demo能够跳转
先回到App.js
页面 设置首页导航栏标题
static navigationOptions = ({ navigation }) => {
const { params = {} } = navigation.state
const onPressRightButtonFunc = params.openPublisher || function () { }
return {
title: '首页',
}
}
复制代码
引入TouchableOpacity
设置点击事件
import { TouchableOpacity } from "react-native";
...
...
renderMovie({ item }) {
const navigate = this.props.navigation;
return (
<TouchableOpacity activeOpacity={0.5} onPress={() => navigate.navigate('Details')} > //'Details'是以前在navigation.js声明好的了
... //这里是以前item的UI代码
</TouchableOpacity>
复制代码
到这里基本已经完成了这个demo,其余的都是一些重复的UI工做也不赘述了,这是稍微优化过的代码和详情页,看不懂的能够根据根据这源码来。
这里个人源码是将基本组件都下好,下载运行便可,由于比较大先上传到百度云。
连接: pan.baidu.com/s/1854tyx1R… 提取码: kgmb
网上的其余demo对新人都很不友好,须要安装各个组件再运行起来,各类报错容易劝退新人
初衷是想让新手快速的入门制做一个demo,后面发现仍是须要一点web经验的,内容有点多,说得没那么细致的地方请见谅。后续会一直持续更新这个demo;
若是以为对这篇文章对您有一点帮助的话,欢迎关注,戳这里 → 芦苇科技