React Navigation 構建 Android 和 iOS 統一的 UI

React Navigation 是 React Native 項目經常使用的路由和導航庫,經過它咱們能夠很輕鬆的構建多個頁面並完成頁面的跳轉。不過,由於 iOS 和 Android 在設計風格上的差別,React Navigation 在不一樣平臺上的表現也不一樣。例如,切換 StackNavigator 頁面時,iOS 是從右側滑入,而 Android 是從底部滑入。 在 React Native 項目中,有時咱們想要構建 iOS 和 Android 統一的 UI,這時咱們就須要對 React Navigation 的默認配置進行一些修改。本文以 iOS 風格爲主,介紹如何構建在 Android 上表現相同的 UI。java

主要的差別

開始以前,先看一下 iOS 和 Android 之間有哪些差別,這樣咱們才清楚本身要作什麼。react

狀態欄

iOS 中 App 是全屏模式,狀態欄不佔據佈局空間。android

Android 中狀態欄默認是佔據佈局空間的。git

Header

在 iOS 中,Header 的高度是 44,標題居中,底部有邊框,返回按鈕圖標是「<」。github

在 Android 中,Header 的高度是 56,標題居左,底部有陰影,返回按鈕圖標是「←」。react-native

同時在標題的字體上也存在差別。app

頁面切換效果

iOS 是從右側滑入劃出,而 Android 是從底部的淡入淡出。佈局

同時,咱們還能夠注意到在切換時,iOS 的 Header 是固定在頂部的,而 Android 是隨頁面一塊兒切換的(Android 截圖不便,這裏就沒有貼出)。post

統一 UI

在瞭解完差別之後,如今來看看怎麼抹平這些差別來實現統一的 UI(iOS 風格)。字體

狀態欄

此前對狀態欄這一塊理解還不夠深,不少東西沒有說清楚,因此我又從新寫了一篇博客全面的介紹了關於狀態欄的問題。

在 iOS 中頁面是全屏的,狀態欄不佔空間,頁面內容會上移到狀態欄下面(這是 iOS 中有 SafeAreaView 的緣由之一),而Android 中默認狀態欄是佔空間的。一般這沒有什麼問題,可是當咱們須要設置全屏背景或者頁面頂部有背景圖片時,Android 上的體驗就較差了。

幸虧,在 Android 4.4 之後,經過 FLAG_TRANSLUCENT_STATUS 屬性能夠將狀態欄設置成不佔據佈局空間的透明樣式。咱們能夠在 Android 代碼中設置:

activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
複製代碼

也能夠在 theme 中設置 windowTranslucentStatus

<!-- android/app/src/main/res/values/styles.xml -->

<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar"> <item name="android:windowTranslucentStatus">true</item></style>
複製代碼

還能夠經過 StatusBartranslucent 屬性進行設置。

<StatusBar translucent />
複製代碼

設置完之後效果以下圖。

從圖中能夠看出,狀態欄如今不佔據空間,內容上移致使狀態欄和標題欄重疊了。爲了讓標題欄回到原來的位置,咱們須要增長 Header 的高度,而且添加一個上邊距,大小爲狀態欄的高度:

static navigationOptions = {
  title: 'PageB',
  headerStyle: Platform.OS === 'android' ? {
    paddingTop: StatusBar.currentHeight,
    height: StatusBar.currentHeight + 56,
  } : {}
}
複製代碼

同時,還能夠看到狀態欄並非徹底透明的,而是有一點淺灰色,這時咱們就須要使用 Android 5.0 之後的 API 來將狀態欄設置爲透明。

activity.getWindow().setStatusBarColor(Color.TRANSPARENT);
複製代碼

還能夠經過 StatusBarbackgroundColor 屬性進行設置。

<StatusBar backgroundColor="transparent" />
複製代碼

網上還搜索到能夠經過 xml 的方式進行設置,可是我幾番嘗試後發現沒有效果,不知道具體什麼緣由。

<item name="android:statusBarColor">@android:color/transparent</item>
複製代碼

Header 和過渡效果

Header 和過濾效果咱們均可以經過 createStackNavigator 暴露出來的屬性來進行配置。

{
  defaultNavigationOptions: {
    headerTitleStyle: {
      fontSize: 17,
    }
  },
  headerMode: 'float', // 公用一個頂部 Header,頁面切換時顯示動畫
  headerLayoutPreset: 'center' // 標題居中
}
複製代碼

參考連接

相關文章
相關標籤/搜索