React Navigation header 按鈕及導(dǎo)航嵌套

在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>
  );
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市厉亏,隨后出現(xiàn)的幾起案子董习,更是在濱河造成了極大的恐慌,老刑警劉巖爱只,帶你破解...
    沈念sama閱讀 211,348評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件皿淋,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)窝趣,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,122評論 2 385
  • 文/潘曉璐 我一進(jìn)店門疯暑,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人哑舒,你說我怎么就攤上這事妇拯。” “怎么了洗鸵?”我有些...
    開封第一講書人閱讀 156,936評論 0 347
  • 文/不壞的土叔 我叫張陵越锈,是天一觀的道長。 經(jīng)常有香客問我膘滨,道長甘凭,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,427評論 1 283
  • 正文 為了忘掉前任火邓,我火速辦了婚禮丹弱,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘铲咨。我一直安慰自己蹈矮,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,467評論 6 385
  • 文/花漫 我一把揭開白布鸣驱。 她就那樣靜靜地躺著,像睡著了一般蝠咆。 火紅的嫁衣襯著肌膚如雪踊东。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,785評論 1 290
  • 那天刚操,我揣著相機(jī)與錄音闸翅,去河邊找鬼。 笑死菊霜,一個(gè)胖子當(dāng)著我的面吹牛坚冀,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播鉴逞,決...
    沈念sama閱讀 38,931評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼记某,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了构捡?” 一聲冷哼從身側(cè)響起液南,我...
    開封第一講書人閱讀 37,696評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎勾徽,沒想到半個(gè)月后滑凉,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,141評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,483評論 2 327
  • 正文 我和宋清朗相戀三年畅姊,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了咒钟。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,625評論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡若未,死狀恐怖朱嘴,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情陨瘩,我是刑警寧澤腕够,帶...
    沈念sama閱讀 34,291評論 4 329
  • 正文 年R本政府宣布,位于F島的核電站舌劳,受9級特大地震影響帚湘,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜甚淡,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,892評論 3 312
  • 文/蒙蒙 一大诸、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧贯卦,春花似錦资柔、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,741評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至啡彬,卻和暖如春羹与,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背庶灿。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評論 1 265
  • 我被黑心中介騙來泰國打工纵搁, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人往踢。 一個(gè)月前我還...
    沈念sama閱讀 46,324評論 2 360
  • 正文 我出身青樓腾誉,卻偏偏與公主長得像,于是被迫代替她去往敵國和親峻呕。 傳聞我的和親對象是個(gè)殘疾皇子利职,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,492評論 2 348

推薦閱讀更多精彩內(nèi)容