今日關鍵字:Splash Screen
初始畫面是點擊App後首先出現的畫面
(像是打開推特時那隻鳥會從標誌放大到整個畫面)
這個需要原生來處理
而今天先試著以別的方式來模仿這個效果
由於React Native內能處理到的地方最早只能從App開始跑的地方開始
所以再怎麼模仿跟原生的表現還是有所差別
如果很在意的話還是只能從原生下手
這裡需要多包一層Stack.Navigator
// App.tsx
const App = () => (
<Provider store={store}>
{/* <Navigation /> */}
<NavigationContainer>
<!--1.-->
<Stack.Navigator headerMode="none">
<Stack.Screen
name="SplashScreen"
options={() => ({ animationEnabled: false, headerShown: false })}
component={SplashScreen}
/>
<!--2.-->
<Stack.Screen
name="Navigation"
options={() => ({ animationEnabled: false, headerShown: false })}
component={Navigation}
/>
</Stack.Navigator>
</NavigationContainer>
</Provider>
)
因為外面已經包了<NavigationContainer>
,所以要移除Navigation
裡的那個
// Navigation.tsx
...
return (
</>
// <NavigationContainer>
...
這裡要注意的點有兩個
<Stack.Navigator">
需加上headerMode="none"
有加
沒加
可以看到如果不去除header,會把下層的覆蓋過去
{ animationEnabled: false }
<Stack.Screen>
的options如果不取消預設的過場動畫,會有很明顯的換頁感
跟期望的效果有所差別,當然這裡也可以調整transition達成自己喜歡的過場效果
最後把想要呈現的初始畫面寫出來
再以useEffect
撰寫換頁條件就可以了
(我這裡是先打API拿到資料後才跳轉首頁)
import React, { useEffect } from 'react'
import { View, StyleSheet, Image, Text } from 'react-native'
import { useNavigation } from '@react-navigation/native'
import { useDispatch, useSelector } from 'react-redux'
import splashIcon from '../assets/splash_icon.png'
import { RootStateType } from '../redux/reducer/rootReducer'
import { getAllAnimeBegin } from '../redux/action/animeAction'
import { getLanguageBegin } from '../redux/action/languageAction'
const SplashScene = () => {
const navigation = useNavigation()
const dispatch = useDispatch()
const allAnime = useSelector((state: RootStateType) => state.allAnime)
useEffect(() => {
dispatch(getLanguageBegin())
dispatch(getAllAnimeBegin())
}, [])
useEffect(() => {
if (allAnime.length > 0) {
// @ts-ignore
// navigation.replace('Navigation')
navigation.reset({
index: 0,
routes: [
{
name: 'Navigation'
}
]
})
}
}, [allAnime])
return (
<View style={styles.container}>
<Image source={splashIcon} />
<Text style={styles.loading}>Loading...</Text>
</View>
)
}
這裡跳轉回首頁的方法不是之前一直在用的
navigation.navigate()
而是
navigation.replace()
或是
navigation.reset()
navigate()
的操作類似於web的pushstate,會留下前一頁的紀錄
也就是當回到首頁後會出現上一頁的按鈕
網路上有人說:可以把header藏起來就好
但這裡要注意的是,剛剛已經把上層的header藏起來了
下層的header也還是會有那個按鈕
把header藏起來的做法顯然是個治標不治本的做法
這裡有個奇怪的地方是
如果直接這樣用
navigation.replace(...)
會跳出錯誤
如果試著印出navigation
的確有replace()
,重要的是的確可以正常使用...
只能這樣了
// @ts-ignore
navigation.replace('Navigation')
摀住lint的嘴巴
明天改來試試看原生的Splash Screen