在header增加按鈕
與header交互的最常見方式是點(diǎn)擊title左邊或右邊的按鈕改览。讓我們在header右側(cè)添加一個(gè)按鈕(這是整個(gè)屏幕上最難觸碰的地方之一下翎,取決于手指和手機(jī)的大小,但也是放置按鈕的正常位置)
function StackScreen() {
return (
<Stack.Navigator>
<Stack.Screen
name="Home"
component={HomeScreen}
options={{
headerTitle: props => <LogoTitle {...props} />,
headerRight: () => (
<Button
onPress={() => alert('This is a button!')}
title="Info"
color="#fff"
/>
),
}}
/>
</Stack.Navigator>
);
}
當(dāng)我們以這種方式定義按鈕時(shí)宝当,options中的this變量不是homesscreen實(shí)例视事,所以你不能在它上面調(diào)用setState或任何實(shí)例方法。這是非常重要的庆揩,因?yàn)樗欠浅3R姷睦M粹o在你的頭部與屏幕交互的頭部所屬。下面我們來看看如何做這個(gè)订晌。
頭部與其屏幕組件的交互
為了能夠與屏幕組件交互虏辫,我們需要使用navigation.setOptions
定義按鈕而不是options
屬性。通過在screen組件中使用navigation.setOptions
锈拨,我們可以訪問screen的props砌庄、state、context等。
function StackScreen() {
return (
<Stack.Navigator>
<Stack.Screen
name="Home"
component={HomeScreen}
options={({ navigation, route }) => ({
headerTitle: props => <LogoTitle {...props} />,
})}
/>
</Stack.Navigator>
);
}
function HomeScreen({ navigation }) {
const [count, setCount] = React.useState(0);
React.useLayoutEffect(() => {
navigation.setOptions({
headerRight: () => (
<Button onPress={() => setCount(c => c + 1)} title="Update count" />
),
});
}, [navigation]);
return <Text>Count: {count}</Text>;
}
導(dǎo)航嵌套
嵌套導(dǎo)航器意味著在一個(gè)導(dǎo)航器的屏幕中嵌套另一個(gè)導(dǎo)航器鹤耍。
下面的例子中肉迫,Home組件包含一個(gè)選項(xiàng)卡導(dǎo)航器。Home組件也用于App組件內(nèi)部堆棧導(dǎo)航器的Home屏幕稿黄。這里喊衫,標(biāo)簽導(dǎo)航器嵌套在堆棧導(dǎo)航器中:
function Home() {
return (
<Tab.Navigator>
<Tab.Screen name="Feed" component={Feed} />
<Tab.Screen name="Messages" component={Messages} />
</Tab.Navigator>
);
}
function App() {
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen
name="Home"
component={Home}
options={{ headerShown: false }}
/>
<Stack.Screen name="Profile" component={Profile} />
<Stack.Screen name="Settings" component={Settings} />
</Stack.Navigator>
</NavigationContainer>
);
}
嵌套導(dǎo)航器特性
- 每個(gè)導(dǎo)航器保存自己的導(dǎo)航歷史
- 例如,當(dāng)你在嵌套堆棧導(dǎo)航器的屏幕內(nèi)按下后退按鈕時(shí)杆怕,即使有另一個(gè)導(dǎo)航器作為父導(dǎo)航器族购,它也會回到嵌套堆棧內(nèi)的上一個(gè)屏幕
- 每個(gè)導(dǎo)航器都有自己的選項(xiàng)
- 例如,在嵌套在子導(dǎo)航器中的屏幕中指定標(biāo)題選項(xiàng)不會影響在父導(dǎo)航器中顯示的標(biāo)題
- 導(dǎo)航器中的每個(gè)屏幕都有自己的參數(shù)
- 例如陵珍,任何傳遞到嵌套導(dǎo)航器中的屏幕的參數(shù)都在該屏幕的路由道具中寝杖,不能從父或子導(dǎo)航器中的屏幕訪問
- 導(dǎo)航操作由當(dāng)前導(dǎo)航器處理,如果不能處理互纯,則彈出
- 導(dǎo)航器特定的方法可以在嵌套的導(dǎo)航器中使用
- 嵌套導(dǎo)航器不接收父級事件
- 父導(dǎo)航器的UI呈現(xiàn)在子導(dǎo)航器之上
在嵌套導(dǎo)航器中導(dǎo)航到屏幕
function Root() {
return (
<Drawer.Navigator>
<Drawer.Screen name="Home" component={Home} />
<Drawer.Screen name="Profile" component={Profile} />
<Stack.Screen name="Settings" component={Settings} />
</Drawer.Navigator>
);
}
function App() {
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen
name="Root"
component={Root}
options={{ headerShown: false }}
/>
<Stack.Screen name="Feed" component={Settings} />
</Stack.Navigator>
</NavigationContainer>
);
}
在這里瑟幕,你可能想從Feed組件導(dǎo)航到Root屏幕
navigation.navigate('Root');
它可以工作,并顯示Root組件內(nèi)部的初始屏幕留潦,即Home只盹。但有時(shí)您可能想要控制應(yīng)該在導(dǎo)航中顯示的屏幕。要實(shí)現(xiàn)它兔院,你可以在參數(shù)中傳遞屏幕的名稱:
navigation.navigate('Root', { screen: 'Profile' });
在嵌套導(dǎo)航器中向屏幕傳遞參數(shù)
navigation.navigate('Root', {
screen: 'Profile',
params: { user: 'jane' },
});
navigation.navigate('Root', {
screen: 'Settings',
params: {
screen: 'Sound',
params: {
screen: 'Media',
},
},
});
呈現(xiàn)導(dǎo)航器中定義的初始路由
默認(rèn)情況下殖卑,當(dāng)您在嵌套導(dǎo)航器中導(dǎo)航一個(gè)屏幕時(shí),指定的屏幕將被用作初始屏幕坊萝,導(dǎo)航器上的初始路由道具將被忽略孵稽。這個(gè)行為不同于React Navigation 4。
如果你需要呈現(xiàn)導(dǎo)航器中指定的初始路由十偶,你可以通過設(shè)置initial: false來禁用使用指定屏幕作為初始屏幕的行為:
navigation.navigate('Root', {
screen: 'Settings',
initial: false,
});
嵌套多個(gè)導(dǎo)航器
當(dāng)嵌套多個(gè)堆棧菩鲜、抽屜或底部選項(xiàng)卡導(dǎo)航器時(shí),將同時(shí)顯示子導(dǎo)航器和父導(dǎo)航器的標(biāo)題惦积。然而睦袖,通常更可取的做法是在子導(dǎo)航器中顯示標(biāo)題,并在父導(dǎo)航器的屏幕中隱藏標(biāo)題荣刑。
function Home() {
return (
<Tab.Navigator>
<Tab.Screen name="Profile" component={Profile} />
<Tab.Screen name="Settings" component={Settings} />
</Tab.Navigator>
);
}
function App() {
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen
name="Home"
component={Home}
options={{ headerShown: false }}
/>
<Stack.Screen name="EditPost" component={EditPost} />
</Stack.Navigator>
</NavigationContainer>
);
}
如果你不希望標(biāo)題出現(xiàn)在任何導(dǎo)航器中馅笙,你可以在所有導(dǎo)航器中指定headerShown: false:
function Home() {
return (
<Tab.Navigator screenOptions={{ headerShown: false }}>
<Tab.Screen name="Profile" component={Profile} />
<Tab.Screen name="Settings" component={Settings} />
</Tab.Navigator>
);
}
function App() {
return (
<NavigationContainer>
<Stack.Navigator screenOptions={{ headerShown: false }}>
<Stack.Screen name="Home" component={Home} />
<Stack.Screen name="EditPost" component={EditPost} />
</Stack.Navigator>
</NavigationContainer>
);
}