先看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;
若是以爲對這篇文章對您有一點幫助的話,歡迎關注,戳這裏 → 蘆葦科技