我已按照示例here进行操作,然后尝试添加标题。我设法获得了显示密钥和后退导航的标题,以显示堆栈中前一张卡的密钥。
我遇到的问题是我无法弄清楚如何对齐后退动作的图标和文字。如果我将flow: 1
添加到样式中,那么它就会消失。如果我添加任何对齐选项,则没有任何变化。 Funnilly足够了,改变flexDirection的工作原理,以及改变左右边距。
现在,图标和文字似乎沿着上边缘对齐。
我不确定它是文本问题还是容器大小问题。请注意,我在文本上尝试textAlignVertical: 'center'
无济于事。
我该怎么做?
有谁知道如何解决?
有问题的代码:
/**
* Sample React Native App
* https://github.com/facebook/react-native
* @flow
*
* Refer: http://facebook.github.io/react-native/docs/navigation.html
*/
import React, { Component } from 'react';
import {
AppRegistry,
NavigationExperimental,
PixelRatio,
ScrollView,
StyleSheet,
View,
Text,
TouchableHighlight
} from 'react-native';
import Icon from 'react-native-vector-icons/Ionicons'
const {
CardStack: NavigationCardStack,
StateUtils: NavigationStateUtils,
Header: NavigationHeader,
} = NavigationExperimental;
export default class BleedingEdgeApplication extends Component {
constructor(props, context) {
super(props, context);
this.state = {
navigationState: {
index: 0,
routes: [{key: 'Home'}]
}
}
this._onNavigationChange = this._onNavigationChange.bind(this);
}
_onNavigationChange(type) {
// extract the navigation state from the current state
let {navigationState} = this.state;
switch(type) {
case 'push':
// push a new route, which in our case is an object with a key value
const route = {key: ':' + Date.now()};
// use the push reducer provided by NavigationStateUtils
navigationState = NavigationStateUtils.push(navigationState, route);
break;
case 'pop':
// Pop the current route using the pop reducer
navigationState = NavigationStateUtils.pop(navigationState);
break;
}
if (this.state.navigationState !== navigationState) {
this.setState({navigationState});
}
}
render() {
return (
<MyVerySimpleNavigator
navigationState={this.state.navigationState}
onNavigationChange={this._onNavigationChange}
onExit={this._exit}
/>
);
}
}
class TappableRow extends Component {
render () {
return (
<TouchableHighlight
style={styles.row}
underlayColor="#D0D0D0"
onPress={this.props.onPress}>
<Text style={styles.buttonText}>
{this.props.text}
</Text>
</TouchableHighlight>
);
}
}
class MyVeryComplexScene extends Component {
render() {
return (
<ScrollView style={styles.scrollView}>
<Text style={styles.row}>
Route: {this.props.route.key}
</Text>
<TappableRow
text="Tap me to load the next scene"
onPress={this.props.onPushRoute}
/>
<TappableRow
text="Tap me to go back"
onPress={this.props.onPopRoute}
/>
</ScrollView>
);
}
}
class MyVerySimpleNavigator extends Component {
constructor(props, context) {
super(props, context);
this._onPushRoute = this.props.onNavigationChange.bind(null, 'push');
this._onPopRoute = this.props.onNavigationChange.bind(null, 'pop');
this._renderScene = this._renderScene.bind(this);
this._renderHeader = this._renderHeader.bind(this);
this._renderLeftHeader = this._renderLeftHeader.bind(this);
}
render() {
return (
<NavigationCardStack
onNavigateBack={this._onPopRoute}
navigationState={this.props.navigationState}
renderScene={this._renderScene}
renderHeader={this._renderHeader}
style={styles.navigator}
/>
);
}
_renderHeader(sceneProps) {
return (
<NavigationHeader
{...sceneProps}
renderTitleComponent={() => (
<NavigationHeader.Title>
{sceneProps.scene.route.key}
</NavigationHeader.Title>
)}
renderLeftComponent={this._renderLeftHeader}
/>
);
}
_renderLeftHeader(sceneProps) {
if(sceneProps.scene.index > 0) {
return (
<TouchableHighlight onPress={this._onPopRoute}>
<View style={styles.backView}>
<Icon style={styles.navBarIcon} name='ios-arrow-back' size={27} />
<Text style={styles.backText}>{sceneProps.scenes[sceneProps.scene.index - 1].route.key}</Text>
</View>
</TouchableHighlight>
);
}
return (
<TouchableHighlight>
<View style={styles.backView}>
<Icon style={styles.navBarIcon} name='ios-menu' size={27} />
</View>
</TouchableHighlight>
);
}
_renderScene(sceneProps) {
return (
<MyVeryComplexScene
route={sceneProps.scene.route}
onPushRoute={this._onPushRoute}
onPopRoute={this._onPopRoute}
onExit={this.props.onExit}
/>
);
}
}
const styles = StyleSheet.create({
navigator: {
flex: 1,
},
scrollView: {
marginTop: 64
},
row: {
padding: 15,
backgroundColor: 'white',
borderBottomWidth: 1 / PixelRatio.get(),
borderBottomColor: '#CDCDCD',
},
backView: {
// flex: 2,
height: 50,
flexDirection: 'row',
justifyContent: 'center',
alignItems: 'flex-start',
},
backText: {
fontSize: 12,
textAlign: 'left',
},
backChevron: {
},
navBarIcon: {
color: '#1d1d1d',
marginLeft: 8,
marginRight: 8,
justifyContent: 'center',
},
rowText: {
fontSize: 17,
},
buttonText: {
fontSize: 17,
fontWeight: '500',
},
});
AppRegistry.registerComponent('BleedingEdgeApplication', () => BleedingEdgeApplication);
我应该注意到我正在使用React Native Vector Icons。这需要将Ionicon字体从字体的目录复制到ios项目中并从xcode中重建。
答案 0 :(得分:0)
问题不是将样式应用于<TouchableHighlight>
flex: 1
。这使得组件占用整个空间,让我在保持按钮和文本的<View>
上使用flex和alignItems。这使整个造型更加整洁。
最大的困惑是理解<NavigationHeader>
中的各种标题组件都是独立的,因此左右都是标题的单独渲染选项。
代码正常工作(带有彩色背景以显示组件):
/**
* Sample React Native App
* https://github.com/facebook/react-native
* @flow
*
* Refer: http://facebook.github.io/react-native/docs/navigation.html
*/
import React, { Component } from 'react';
import {
AppRegistry,
NavigationExperimental,
PixelRatio,
ScrollView,
StyleSheet,
View,
Text,
TouchableHighlight
} from 'react-native';
import Icon from 'react-native-vector-icons/Ionicons'
const {
CardStack: NavigationCardStack,
StateUtils: NavigationStateUtils,
Header: NavigationHeader,
} = NavigationExperimental;
export default class BleedingEdgeApplication extends Component {
constructor(props, context) {
super(props, context);
this.state = {
navigationState: {
index: 0,
routes: [{key: 'Home'}]
}
}
this._onNavigationChange = this._onNavigationChange.bind(this);
}
_onNavigationChange(type) {
// extract the navigation state from the current state
let {navigationState} = this.state;
switch(type) {
case 'push':
// push a new route, which in our case is an object with a key value
const route = {key: ':' + Date.now()};
// use the push reducer provided by NavigationStateUtils
navigationState = NavigationStateUtils.push(navigationState, route);
break;
case 'pop':
// Pop the current route using the pop reducer
navigationState = NavigationStateUtils.pop(navigationState);
break;
}
if (this.state.navigationState !== navigationState) {
this.setState({navigationState});
}
}
render() {
return (
<MyVerySimpleNavigator
navigationState={this.state.navigationState}
onNavigationChange={this._onNavigationChange}
onExit={this._exit}
/>
);
}
}
class TappableRow extends Component {
render () {
return (
<TouchableHighlight
style={styles.row}
underlayColor="#D0D0D0"
onPress={this.props.onPress}>
<Text style={styles.buttonText}>
{this.props.text}
</Text>
</TouchableHighlight>
);
}
}
class MyVeryComplexScene extends Component {
render() {
return (
<ScrollView style={styles.scrollView}>
<Text style={styles.row}>
Route: {this.props.route.key}
</Text>
<TappableRow
text="Tap me to load the next scene"
onPress={this.props.onPushRoute}
/>
<TappableRow
text="Tap me to go back"
onPress={this.props.onPopRoute}
/>
</ScrollView>
);
}
}
class MyVerySimpleNavigator extends Component {
constructor(props, context) {
super(props, context);
this._onPushRoute = this.props.onNavigationChange.bind(null, 'push');
this._onPopRoute = this.props.onNavigationChange.bind(null, 'pop');
this._onOpenSideNav = this._onOpenSideNav.bind(this);
this._renderScene = this._renderScene.bind(this);
this._renderHeader = this._renderHeader.bind(this);
this._renderLeftHeader = this._renderLeftHeader.bind(this);
}
render() {
return (
<NavigationCardStack
onNavigateBack={this._onPopRoute}
navigationState={this.props.navigationState}
renderScene={this._renderScene}
renderHeader={this._renderHeader}
style={styles.navigator}
/>
);
}
_renderHeader(sceneProps) {
return (
<NavigationHeader
{...sceneProps}
style={styles.navHeader}
renderTitleComponent={() => (
<NavigationHeader.Title style={styles.navheadertitle}>
<Text style={styles.headerTitle}>
{sceneProps.scene.route.key}
</Text>
</NavigationHeader.Title>
)}
renderLeftComponent={this._renderLeftHeader}
/>
);
}
_renderLeftHeader(sceneProps) {
if(sceneProps.scene.index > 0) {
return (
<TouchableHighlight onPress={this._onPopRoute} style={styles.headerBackTouchableHighlight}>
<View style={styles.headerBackView}>
<Icon style={styles.headerIcon} name='ios-arrow-back' size={27} />
<Text style={styles.headerBackText}>{sceneProps.scenes[sceneProps.scene.index - 1].route.key}</Text>
</View>
</TouchableHighlight>
);
}
return (
<TouchableHighlight onPress={this._onOpenSideNav} style={styles.headerBackTouchableHighlight}>
<View style={styles.headerBackView}>
<Icon style={styles.headerIcon} name='ios-menu' size={27} />
</View>
</TouchableHighlight>
);
}
_renderScene(sceneProps) {
return (
<MyVeryComplexScene
route={sceneProps.scene.route}
onPushRoute={this._onPushRoute}
onPopRoute={this._onPopRoute}
onExit={this.props.onExit}
/>
);
}
_onOpenSideNav() {
return null;
}
}
const styles = StyleSheet.create({
navigator: {
},
navHeader: {
backgroundColor: 'red',
},
navheadertitle: {
backgroundColor: '#00ff0099',
flex: 3
},
headerTitle: {
color: '#ffffff',
backgroundColor: 'blue',
},
headerBackTouchableHighlight: {
backgroundColor: 'purple',
flex: 1,
},
headerBackView: {
flex: 1,
flexDirection: 'row',
alignItems: 'center',
backgroundColor: 'darkgreen',
},
headerBackText: {
fontSize: 14,
textAlign: 'left',
color: '#ffffff',
},
headerIcon: {
color: '#ffffff',
marginLeft: 8,
marginRight: 8,
justifyContent: 'center',
},
scrollView: {
marginTop: 64
},
row: {
padding: 15,
backgroundColor: 'white',
borderBottomWidth: 1 / PixelRatio.get(),
borderBottomColor: '#CDCDCD',
},
rowText: {
fontSize: 17,
},
buttonText: {
fontSize: 17,
fontWeight: '500',
},
});
AppRegistry.registerComponent('BleedingEdgeApplication', () => BleedingEdgeApplication);