標籤:
之前我們學習了可觸摸組件和頁面導航的使用的使用:
從零學React Native之09可觸摸組件
…
從零學React Native之03頁面導航
…
經過之前的學習, 我們可以完成一個自訂導覽列了, 效果如下:
我們需要建立一個 NaviBar.js
用來顯示頂部的導覽列, 還需要四個介面(Page1.js,Page2.js,Page3.js,Page4.js
)。 當然還需要修改index.android.js
或者index.ios.js
用來處理4個介面的切換。
導覽列NaviBar 實現
這裡, 我們就假設應用有4個欄目, 每個按鈕的寬高比為 4:3
直接貼代碼了:
import React, { Component } from ‘react‘;import { AppRegistry, StyleSheet, View, Text, TouchableHighlight,} from ‘react-native‘;var Dimensions = require("Dimensions");var totalWidth = Dimensions.get(‘window‘).width;// 螢幕寬度let naviButtonWidth = totalWidth / 4; //計算導航條每個寬度let naviButtonHeight = naviButtonWidth * 0.75; // 導航條每個高度export default class NaviBar extends Component { // 構造 constructor(props) { super(props); this._tab0Pressed = this._tab0Pressed.bind(this); this._tab1Pressed = this._tab1Pressed.bind(this); this._tab2Pressed = this._tab2Pressed.bind(this); this._tab3Pressed = this._tab3Pressed.bind(this); } //四個按鈕 被按下時處理函數 _tab0Pressed() { this.props.onNaviBarPress(0); } _tab1Pressed() { this.props.onNaviBarPress(1); } _tab2Pressed() { this.props.onNaviBarPress(2); } _tab3Pressed() { this.props.onNaviBarPress(3); } render() { //通過屬性得知哪個導覽按鈕是當前置航頁, 這個導航用灰色背景 //利用JavaScript數組的map函數,從一個數組對應產生另一個數組buttonColors // 看不懂該函數的,看下面的解釋 var buttonColors = this.props.naviBarStatus.map(function (aNumber) { if (aNumber == 0) return ‘white‘; return ‘gray‘; }); return ( //根View <View style={styles.naviRow}> <TouchableHighlight onPress={this._tab0Pressed}> <View style={[styles.button,{backgroundColor:buttonColors[0]}]}> <Text style={styles.textStyle1}> 條目一 </Text> </View> </TouchableHighlight> <TouchableHighlight onPress={this._tab1Pressed}> <View style={[styles.button,{backgroundColor:buttonColors[1]}]}> <Text style={styles.textStyle1}> 條目二 </Text> </View> </TouchableHighlight> <TouchableHighlight onPress={this._tab2Pressed}> <View style={[styles.button,{backgroundColor:buttonColors[2]}]}> <Text style={styles.textStyle1}> 條目三 </Text> </View> </TouchableHighlight> <TouchableHighlight onPress={this._tab3Pressed}> <View style={[styles.button,{backgroundColor:buttonColors[3]}]}> <Text style={styles.textStyle1}> 條目四 </Text> </View> </TouchableHighlight> </View> ); }}// 聲明屬性, 方便使用當前組件NaviBar.propTypes = { naviBarStatus: React.PropTypes.arrayOf(React.PropTypes.number).isRequired, onNaviBarPress: React.PropTypes.func.isRequired};//樣式 const styles = StyleSheet.create({ naviRow: { flexDirection: ‘row‘ }, button: { width: naviButtonWidth, height: naviButtonHeight, justifyContent: ‘center‘ }, textStyle1: { fontSize: 20, textAlign: ‘center‘ }});
上面用到了, Map函數 ,
Map函數的作用是按照某種關係從原數組”映射”出新數組. 如下面求平方的例子:
var data= [1,2,3,4];var newArray=data.map((item)=>{return item*item});console.log(newArray); //輸出[1,4,9,16]
統一處理四個介面的切換
我們需要在index.android.js 或者index.ios.js 這個代碼比較簡單, 只需要匯入四個介面, 用Navigator組件切換就可以了。
import React, { Component } from ‘react‘;import { AppRegistry, StyleSheet, Navigator} from ‘react-native‘;import Page1 from ‘./Page1‘;import Page2 from ‘./Page2‘;import Page3 from ‘./Page3‘;import Page4 from ‘./Page4‘;class AwesomeProject extends Component { //告知Navigator 模組切換時的效果 configureScene() { return Navigator.SceneConfigs.FadeAndroid; } //根據傳遞的資訊, 處理介面的切換 renderScene(router, navigator) { this._navigator = navigator; switch (router.name) { case ‘Page1‘: return <Page1 navigator={navigator}/>; case ‘Page2‘: return <Page2 navigator={navigator}/>; case ‘Page3‘: return <Page3 navigator={navigator}/>; case ‘Page4‘: return <Page4 navigator={navigator}/>; } } render() { return ( //根View <Navigator initialRoute={{name:‘Page1‘}} configureScene={this.configureScene} renderScene={this.renderScene}/> ); }}AppRegistry.registerComponent(‘AwesomeProject‘, () => AwesomeProject);
介面
上面的代碼需要引入Page1 - Page4, 這個四個介面非常相似, 我們只貼其中一個了.
Page1.js
import React, { Component } from ‘react‘;import { View, StyleSheet,} from ‘react-native‘;import NaviBar from ‘./NaviBar‘;export default class Page1 extends Component { // 構造 constructor(props) { super(props); // 初始狀態 this.onNaviBarPress = this.onNaviBarPress.bind(this); } render() { // 不同的Page,需要修改下面的這個數組, 通過數組控制導覽列條目顯示狀態 var naviStatus = [1, 0, 0, 0]; return ( <View style={styles.container}> <NaviBar naviBarStatus={naviStatus} onNaviBarPress={this.onNaviBarPress}/> <View style={styles.whatLeft}/> </View> ); } //不同的page需要修改傳回值 onNaviBarPress(aNumber) { switch (aNumber) { case 0: return; case 1: //通過replace切換 this.props.navigator.replace({ name: ‘Page2‘ }); return; case 2: this.props.navigator.replace({ name: ‘Page3‘ }); return; case 3: this.props.navigator.replace({ name: ‘Page4‘ }); return; } }}const styles = StyleSheet.create({ container: { flex: 1 }, whatLeft: { // 組件定義了一個上邊框 flex: 1, borderTopWidth: 1, borderColor: ‘black‘, backgroundColor:‘red‘ //每個介面背景顏色不一樣 }});
順便指出兩點: 當根View沒有指定背景色時, 預設值是一種灰色; 當子View沒有指定背景色時,會繼承父View的背景色。
更多精彩請關注公眾帳號likeDev,公眾帳號名稱:愛上Android。
React Native自訂導覽列