react native navigator 快速建立換頁功能。
在 react native 中,換頁是不可或缺的功能,
Navigator 即為我們主要使用的原件,
以下步驟將實作出簡單的換頁功能,並且於 app 頂端有導覽列。
引用元件
import {
AppRegistry,
Platform,
TouchableOpacity,
StyleSheet,
Navigator,
View,
Text,
} from 'react-native';
- Platform:可辨別裝置為 ios 或 android
- TouchableOpacity:提供點擊事件 onPress()
- StyleSheet:樣式表
- Navigator:導覽列(本文主要元件)
建立導覽框架
Component:appdemo
class appdemo extends Component {
_renderScene(route, navigator) {
// page router
if (route.component == Main) {
return <Main navigator={navigator} />
}
if (route.component == Home) {
return <Home navigator={navigator} />
}
}
render() {
return (
<Navigator
initialRoute={{ component: Main }}
renderScene={ this._renderScene } />
);
}
}
- initialRoute:設定預設的 component
- renderScene:於換頁時 push component,並依據指定的 component,來載入
Component:Main
class Main extends Component {
_navigate() {
this.props.navigator.push({
component: Home,
})
}
render() {
return (
<View>
<Text>this is Main Page</Text>
<TouchableOpacity onPress= { () => this._navigate() } >
<Text>GO To Home</Text>
</TouchableOpacity>
</View>
);
}
}
- _navigate():透過 onPress 事件,將 navigator push;換到哪一頁,則用 component 來指定欲載入之元件
Component:Home
class Home extends Component {
_back() {
this.props.navigator.pop();
}
render() {
return (
<View style={styles.content}>
<Text>this is Home Page</Text>
<TouchableOpacity onPress= { () => this._back() } >
<Text>GO Back</Text>
</TouchableOpacity>
</View>
);
}
}
- _back:若要返回上一頁,則用 navigator.pop()
StyleSheet:styles
const styles = StyleSheet.create({
content: {
flex: 1,
},
});
AppRegistry:appdemo
AppRegistry.registerComponent('appdemo', () => appdemo);
修改 _renderScene()
在辨別 route 時候,我們用 if 來決定要載入的 component,
但如果今天頁數眾多,將會出現疊羅漢般的 if,
因此我們將原本寫法變更,將取得之元件,以變數形式載入。
_renderScene(route, navigator) {
// 方法一: 用 if 方式選擇 route
// if (route.component == Main) {
// return <Main navigator={navigator} />
// }
// if (route.component == Home) {
// return <Home navigator={navigator} />
// }
// 方法二: 直接把傳來的 component 用變數表示
let Component = route.component;
return (
<Component navigator={navigator} />
);
}
修改換頁動畫 Navigator
在 render Navigator 中我們增加 configureScene ,此可設定頁面滑動的方式(上下、左右)。
render() {
return (
<Navigator
initialRoute={{ component: Main }}
renderScene={ this._renderScene }
configureScene={ this._configureScene } />
);
相對的也建立 _configureScene。
_configureScene(route, routeStack) {
// 頁面滑動方式
return Navigator.SceneConfigs.FloatFromBottom
//return Navigator.SceneConfigs.PushFromRight
}
- FloatFromBottom:由下至上滑入
- PushFromRight:由右往左滑入
增加上方導覽列
在上步驟同樣位置,我們增加 navigationBar,為了調整間距,也增加 sceneStyle。
render() {
return (
<Navigator
initialRoute={{ component: Main }}
renderScene={ this._renderScene }
configureScene={ this._configureScene }
sceneStyle={{ paddingTop: (Platform.OS === 'android' ? 66 : 74) }}
navigationBar={this._renderNavBar() } />
);
建立 _renderNavBar()。
_renderNavBar() {
const styles = {
title: {
flex: 1, alignItems: 'center', justifyContent: 'center'
},
button: {
flex: 1, width: 80, alignItems: 'center', justifyContent: 'center'
},
buttonText: {
fontSize: 18, color: '#FFFFFF', fontWeight: '400'
}
}
var routeMapper = {
LeftButton(route, navigator, index, navState) {
if (index > 0) {
return (
<TouchableOpacity
onPress={() => navigator.pop() }
style={styles.button}>
<Text style={styles.buttonText}>Back</Text>
</TouchableOpacity>
);
} else {
return (
<TouchableOpacity
onPress={() => navigator.pop() }
style={styles.button}>
<Text style={styles.buttonText}>Logo</Text>
</TouchableOpacity>
);
}
},
RightButton(route, navigator, index, navState) {
if (index > 0 && route.rightButton) {
return (
<TouchableOpacity
style={styles.button}>
<Text style={styles.buttonText}>Set</Text>
</TouchableOpacity>
);
} else {
return null
}
},
Title(route, navigator, index, navState) {
return (
<View style={styles.title}>
<Text style={styles.buttonText}>{route.title ? route.title : 'Home'}</Text>
</View>
);
}
};
return (
<Navigator.NavigationBar
style={{
alignItems: 'center',
backgroundColor: '#55ACEE',
}}
routeMapper={routeMapper}
/>
);
}
- 在 routerMapper 中,將設定三種 button 事件以及樣式
- LeftButton:左側按鈕,通常表示 logo 或是 back(返回)
- RightButton:右側按鈕,通常表示 setting 設定
- Title:位於 LeftButton 右側,通常表示當前畫面標題
在頁面中傳入參數 Props
若要在 Main 頁面傳入參數至 Home 頁面參數,必須先修改 _renderScene()。
Component:appdemo
_renderScene(route, navigator) {
let Component = route.component;
return (
<Component navigator={navigator} {...route.passProps} />
);
}
- 在這邊我們追加 { ...route.passProps },於每個 component 進行 props
Component:Main
class Main extends Component {
_navigate(property) {
this.props.navigator.push({
component: Home,
passProps: {
name: property
}
})
}
render() {
return (
<View>
<TouchableOpacity onPress= { () => this._navigate('Hello World') } >
<Text>GO To View</Text>
</TouchableOpacity>
</View>
);
}
}
- _navigate():在裡面加入參數文字 Hello World
- navigator.push:在換頁的時候,將我們剛剛新增的 passProps,新增參數名稱 name(自訂),並傳入 property
在頁面中接收參數 Props
上步驟我們完成了參數之傳遞,接下來要在 Home 這一頁進行接收並顯示。
Component:Home
class Home extends Component {
_back(property) {
this.props.navigator.pop();
}
render() {
const { name } = this.props;
return (
<View style={styles.content}>
<Text>{name}</Text>
<TouchableOpacity onPress= { () => this._back() } >
<Text>GO To View</Text>
</TouchableOpacity>
</View>
);
}
}
- name:由 this.props 可接收 passProps 所有參數,在剛剛我們於 passProps 加入 name,故直接 const { name } 取之。
- 完成後即可看到 Hello World
以上為參考來源之簡易介紹!
參考資料:React Native Navigator — Navigating Like A Pro in React Native
有勘誤之處,不吝指教。ob'_'ov