React Navigation 入门(三) - StackNavigator 属性详解
本节主要讲 StackNavigator 与定义相关的详细属性。 在新的页面被放入栈顶之后,StackNavigator 给你的应用程序提供了切换页面的方法。在 iOS 与 Android 平台上,StackNavigator 默认对应着它们各自的风格,比如在 iOS 上新的页面从右侧滑入,而在 Android 上则是从底部淡入。 首先给出一段代码,以下的内容都在此基础上进行。 class HomeScreen extends Component {
static navigationOptions = {
title: 'Welcome'
};
render() {
const {navigate} = this.props.navigation;
return <View>
<Text>Hello,Chat App!</Text>
<Button
onPress={() => navigate('Chat',{user: 'Lucy'})}
title="Chat with Lucy"
/>
</View>
}
}
const RootNavigator = StackNavigator({
Home: {
screen: HomeScreen
},Chat: {
path: 'people/:name',screen: ChatScreen
}
});
API 定义StackNavigator(RouteConfigs,StackNavigatorConfig)
这里有两个参数 RouteConfigsRouteConfigs(路由配置) 是一组由路由名称与路由设置组成的键值对,它的作用是告诉导航器 Navigator 要显示的页面,格式与结构参考以下代码,注释写得很详细了。 StackNavigator({
// For each screen that you can navigate to,create a new entry like this: // 如果你想导航到一个页面,就按照下面的方式创建它 Chat: { // `ChatScreen` is a React component that will be the main content of the screen. // ChatScreen 就是一个将要显示在屏幕上的 React 组件 screen: ChatScreen,// When `ChatScreen` is loaded by the StackNavigator,it will be given a `navigation` prop. // 当 ChatScreen 被 StackNavigator 加载的时候,它会被赋予一个 navigation 属性 // Optional: When deep linking or using react-navigation in a web app,this path is used: // 可选的:当在 Web 应用程序中进行深度链接或使用 react-navigation 时,才会用到 path path: 'people/:name',// The action and route params are extracted from the path. // action 和 route 的参数是从 path 中提取的 // Optional: Override the `navigationOptions` for the screen // 可选的:可以在这里重写 navigationOptions,你也可以直接写在 ChatScreen 中(上一篇文章讲的) navigationOptions: ({navigation}) => ({ title: `Chat with ${navigation.state.params.user}`,}) },// 以下省略其他的路由(页面) ...MyOtherRoutes });
接下来介绍第二个参数 StackNavigatorConfig路由相关选项:
视觉相关选项:
拿上一篇中的例子来说,有两个页面 Home 与 Chat,我们可以对其进行设置将 Chat 设为首页,并传递参数、设置标题栏等等。 var routeConfigs = {
Home: {
screen: HomeScreen
},Chat: {
screen: ChatScreen,},};
var stackNavigatorConfig = {
initialRouteName: 'Chat',initialRouteParams: {user: 'Join'},// 这里可以对标题栏进行通用设置
// 但是当某个页面也设置了 navigationOptions,则会失效,优先使用页面设置
navigationOptions: {
title: 'Hello Navigation!'
},// 不带标题栏
// headerMode: 'none'
}
const RootNavigator = StackNavigator(routeConfigs,stackNavigatorConfig);
export default RootNavigator;
export default class ChatScreen extends Component {
render() {
const {params} = this.props.navigation.state;
return (
<View>
<Text>Chat with {params.user}</Text>
</View>
);
}
}
效果就像下面这样,具体的各个属性都有什么实际效果,可以自己去尝试一下,有的属性很少会用到。 Screen Navigation Options还记得 title header headerTitle headerTitleAllowFontScaling headerBackTitle headerTruncatedBackTitle headerRight headerLeft headerStyle headerTitleStyle headerBackTitleStyle headerTintColor headerPressColorAndroid gesturesEnabled gestureResponseDistance Navigator Props当 navigator 组件通过
const SomeStack = StackNavigator({
// config
});
<SomeStack
screenProps={/* 这些属性将被传递给在 StackNavigator 中注册的页面, 在这些页面中可以直接通过 this.props.screenProps.xxx 来获取你在这里写的属性 */}
/>
一个自定义页面切换的例子这个例子是官网的,对 const ModalNavigator = StackNavigator(
{
Main: { screen: Main },Login: { screen: Login },{
headerMode: 'none',mode: 'modal',navigationOptions: {
gesturesEnabled: false,transitionConfig: () => ({
transitionSpec: {
duration: 300,easing: Easing.out(Easing.poly(4)),timing: Animated.timing,screenInterpolator: sceneProps => {
const { layout,position,scene } = sceneProps;
const { index } = scene;
const height = layout.initHeight;
const translateY = position.interpolate({
inputRange: [index - 1,index,index + 1],outputRange: [height,0,0],});
const opacity = position.interpolate({
inputRange: [index - 1,index - 0.99,index],outputRange: [0,1,1],});
return { opacity,transform: [{ translateY }] };
},}),}
);
一个自定义标题栏的例子请记住,Header(头部) 是 StackNavigator 特有的。 这个就比较简单了,只是给标题栏加了一个右侧的按钮,我们在上一节的例子上进行修改。 static navigationOptions = ({navigation}) => ({
title: `Chat with ${navigation.state.params.user}`,headerRight: <Button title='Info'/>
});
然后,给右侧按钮添加点击事件。点击按钮之后可以改变标题和按钮的文本。 static navigationOptions = ({navigation}) => {
const {state,setParams} = navigation;
const isInfo = state.params.mode === 'info';
const {user} = state.params;
return {
title: isInfo ? `${user}'s Contact Info` : `Chat with ${state.params.user}`,headerRight: (
<Button
title={isInfo ? 'Done' : `${user}'s info`}
onPress={() => setParams({mode: isInfo ? 'none' : 'info'})}
/>
)
}
};
这里我们用到了 一个顶部标题栏与组件交互的例子有时候,顶部标题需要访问屏幕组件的属性,例如函数或状态。 比方说,我们要创建一个 “编辑联系人信息” 的页面,在标题中有一个保存按钮。我们希望在按下保存按钮之后,按钮被一个 export default class EditInfoScreen extends Component {
static navigationOptions = ({navigation}) => {
const {params = {}} = navigation.state;
let headerRight = (
<Button
title="Save"
onPress={params.handleSave ? params.handleSave : () => null}
/>
);
if (params.isSaving) {
headerRight = <ActivityIndicator/>;
}
return {
title: 'Example',headerRight: headerRight
}
};
state = {
nickname: 'Lucy jacuzzi'
}
_handleSave = () => {
// Update state,show ActivityIndicator
this.props.navigation.setParams({isSaving: true});
// Fictional function to save information in a store somewhere
// saveInfo().then(() => { // this.props.navigation.setParams({isSaving: false}); // }) } componentDidMount() { // We can only set the function after the component has been initialized this.props.navigation.setParams({handleSave: this._handleSave}); } render() { return ( <TextInput onChangeText={(nickname) => this.setState({nickname})} placeholder={'Nickname'} value={this.state.nickname} /> ); } }
代码也很简单,如果你前面的都看过了,再看这里肯定是毫无压力了。效果图: 注意:在这个例子里,参数 本节暂时讲到这里,StackNavigator 的东西太多太杂,梳理起来比较麻烦,所以写的也是比较乱,请大家多多见谅吧。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |