真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

不得不看之ReactNative中的狀態(tài)欄-創(chuàng)新互聯(lián)

預(yù)備知識

創(chuàng)新互聯(lián)主要從事成都網(wǎng)站制作、網(wǎng)站建設(shè)、網(wǎng)頁設(shè)計、企業(yè)做網(wǎng)站、公司建網(wǎng)站等業(yè)務(wù)。立足成都服務(wù)延川,10年網(wǎng)站建設(shè)經(jīng)驗,價格優(yōu)惠、服務(wù)專業(yè),歡迎來電咨詢建站服務(wù):18982081108

在正式開始之前,我先介紹一些我目前了解下來的相關(guān)知識,為后面的內(nèi)容進(jìn)行一些鋪墊。

iOS 中的狀態(tài)欄

在 iOS 中,頁面默認(rèn)全屏(狀態(tài)欄不占空間),狀態(tài)欄內(nèi)容默認(rèn)是深色。因為頁面全屏,所以如果我們不進(jìn)行處理,內(nèi)容會跑到狀態(tài)欄下面去。同時,由于 iPhone X 等劉海屏手機的出現(xiàn),導(dǎo)致狀態(tài)欄的高度發(fā)生了變化,由之前的?20?變成了?34。為了解決此問題,我們可以手動給頂部組件設(shè)置?paddingTop(值根據(jù)機型判斷),或者使用?SafeAreaView?組件。

在 iOS 中我們只用處理好安全區(qū)域的問題,然后根據(jù)頁面的不同去設(shè)置內(nèi)容的顏色深淺即可。

Android 中的狀態(tài)欄

在 Android 中,頁面默認(rèn)非全屏(狀態(tài)欄占空間),狀態(tài)欄內(nèi)容默認(rèn)是淺色。

Android 中對狀態(tài)欄的支持經(jīng)歷了幾個版本:

  • Android4.4(API 19) ~ Android 5.0(API 21):通過?FLAG_TRANSLUCENT_STATUS?設(shè)置頁面為全屏且狀態(tài)欄半透明(淺灰色)。

  • Android 5.0(API 21):提供了?droid:statusBarColor?屬性和?setStatusBarColor?方法用來設(shè)置狀態(tài)欄的顏色。

  • Android 6.0(API 23):通過?SYSTEM_UI_FLAG_LIGHT_STATUS_BAR?支持設(shè)置狀態(tài)欄內(nèi)容為深色。

其中,如果想要設(shè)置狀態(tài)欄顏色,則不能設(shè)置?FLAG_TRANSLUCENT_STATUS

在 Android 應(yīng)用中,每個 Activity 都對應(yīng)一個狀態(tài)欄。這意味著,為一個頁面設(shè)置狀態(tài)欄不會對其他頁面的狀態(tài)欄造成影響。

React Native 中的狀態(tài)欄

React Native 官方提供了?StatusBar?組件用于控制狀態(tài)欄,支持設(shè)置內(nèi)容深淺色,狀態(tài)欄背景(Android)等。

StatusBar?可以同時添加多個,而屬性則會按照加載順序合并(后者覆蓋前者)。

不同于 Android 中的狀態(tài)欄,在 React Native 中狀態(tài)欄是公用的,任何一個地方修改狀態(tài)欄都會導(dǎo)致狀態(tài)欄發(fā)生變化,即使切換到了其他未設(shè)置的頁面。因此,我們需要在每個頁面渲染時都設(shè)置一下相應(yīng)的狀態(tài)欄,或是在離開設(shè)置了狀態(tài)欄的頁面時重置狀態(tài)欄。

實際案例

在了解了必要的知識后,讓我們通過一個實際案例來看看我們需要做什么以及怎么做才更好。

在這個案例中,有三個頁面:主頁,我的,登錄。其中“主頁”和“我的”是兩個標(biāo)簽頁,“主頁”頭部有背景圖片,“我的”頁面頂部是藍(lán)色,“登錄”頁面頂部為白色。頁面效果如下圖。

不得不看之React Native 中的狀態(tài)欄

“主頁”和“我的”頁面使用自定義的 Header,該組件會根據(jù)當(dāng)前設(shè)備,獲取狀態(tài)欄的高度:

const?STATUS_BAR_HEIGHT?=?isiOS()???(isiPhoneX()???34?:?20)?:?StatusBar.currentHeight

其中判斷設(shè)備使用的下面的方法:

//?iPhone?X、iPhone?XS
const?X_WIDTH?=?375;
const?X_HEIGHT?=?812;
//?iPhone?XR、iPhone?XS?Max
const?XSMAX_WIDTH?=?414;
const?XSMAX_HEIGHT?=?896;

const?DEVICE_SIZE?=?Dimensions.get('window');
const?{?height:?D_HEIGHT,?width:?D_WIDTH?}?=?DEVICE_SIZE;

export?const?isiOS?=?()?=>?Platform.OS?===?'ios'

export?const?isiPhoneX?=?()?=>?{
??return?(
????isiOS()?&&
????((D_HEIGHT?===?X_HEIGHT?&&?D_WIDTH?===?X_WIDTH)?||
??????(D_HEIGHT?===?X_WIDTH?&&?D_WIDTH?===?X_HEIGHT))?||
????((D_HEIGHT?===?XSMAX_HEIGHT?&&?D_WIDTH?===?XSMAX_WIDTH)?||
??????(D_HEIGHT?===?XSMAX_WIDTH?&&?D_WIDTH?===?XSMAX_HEIGHT))
??);
};

獲取到狀態(tài)欄的高度之后,根據(jù)當(dāng)前是不是全屏(fullSreen?屬性為?true?或者是 iOS 設(shè)備)來設(shè)置自身高度和?paddingTop,標(biāo)題欄高度統(tǒng)一設(shè)置為?44。

const?headerStyle?=?[
??styles.header,
??(fullScreen?||?isiOS())?&&?{
??????height:?STATUS_BAR_HEIGHT?+?HEADER_HEIGHT,
??????paddingTop:?STATUS_BAR_HEIGHT
??}
]

“登錄”頁面的 Header 則是?react-navigation?默認(rèn)的 Header 組件,在 Android 中標(biāo)題欄高度被設(shè)置為?56。

處理狀態(tài)欄的問題

從上圖的案例中,可以發(fā)現(xiàn)以下幾點問題:

  1. iOS 設(shè)備中,狀態(tài)欄內(nèi)容的顏色顯示不正確,“主頁”和“我的”頁面狀態(tài)欄應(yīng)該是淺色。

  2. Android 設(shè)備中,“主頁”的狀態(tài)欄應(yīng)該是透明的,并且圖片應(yīng)該延伸到狀態(tài)欄下。

  3. Android 設(shè)備中,“我的”頁面狀態(tài)欄顏色應(yīng)該也是藍(lán)色。

為了讓應(yīng)用表現(xiàn)得更好,我們需要根據(jù)頁面動態(tài)的調(diào)整狀態(tài)欄。React Native 為開發(fā)者提供了?StatusBar?組件去控制狀態(tài)欄。

StatusBar 組件控制狀態(tài)欄

我們在“主頁”中,設(shè)置狀態(tài)欄內(nèi)容為“淺色”,背景色為透明,translucent?為?true。然后,“主頁”和“我的”頁面的 Header 都添加?fullScreen?屬性。效果如下:

不得不看之React Native 中的狀態(tài)欄

從圖中可以看到,因為頁面路由是 js 層做的,整個應(yīng)用對應(yīng)一個?StatusBar,雖然“我的”和“登錄”頁面都沒有設(shè)置狀態(tài)欄,但狀態(tài)欄也是透明的。

這樣就有一個問題,“登錄”頁面其實使用默認(rèn)效果即可,但是由于其他頁面設(shè)置了狀態(tài)欄,導(dǎo)致進(jìn)入到“登錄”頁面時效果就不對了。所以,每個頁面都需要設(shè)置相應(yīng)的狀態(tài)欄,因為狀態(tài)欄可能被其他頁面改變。

接下來,在“登錄”頁面設(shè)置狀態(tài)欄為白色且內(nèi)容為深色:

不得不看之React Native 中的狀態(tài)欄

現(xiàn)在“登錄”頁面的效果就和期望的一樣了,當(dāng)我們從“登錄”頁面返回到主界面時,狀態(tài)欄會切換回之前的狀態(tài),但是有一點延時。按照前面的經(jīng)驗,當(dāng)從登錄頁面回來時,狀態(tài)欄應(yīng)該仍是白色且內(nèi)容深色。因為返回時,前面的頁面不會重新渲染,狀態(tài)欄應(yīng)該會保持當(dāng)前的狀態(tài)。但是狀態(tài)欄卻自動調(diào)整成了之前的狀態(tài),雖然有一點延時。我在?react-navigation?的?GitHub issue?中發(fā)現(xiàn)有人提到,當(dāng)離開?route?時,會自動的重設(shè)狀態(tài)欄。我沒有具體研究,但我認(rèn)同這一點,這必然是某處做了此類處理。

那為什么會有延時呢?我猜測這應(yīng)該是自動重置狀態(tài)欄的時機導(dǎo)致的。我嘗試增加了一個注冊頁面(由登錄頁面點擊按鈕進(jìn)入),并設(shè)置狀態(tài)欄為紅色。然后,我在登錄頁面監(jiān)聽了?willFocus?和?didFocus?事件,分別在事件的處理函數(shù)中,將狀態(tài)欄設(shè)置為白色。結(jié)果是,在?willFocus?中處理是我們期望的結(jié)果,而?didFocus?中處理和默認(rèn)不處理時是一樣的。

不得不看之React Native 中的狀態(tài)欄

到這里,我們基本可以得出一個結(jié)論:如果我們要在 app 中調(diào)整狀態(tài)欄,穩(wěn)妥的做法是在每一個頁面?willFocus?時設(shè)置其相應(yīng)的狀態(tài)欄,除非能確保前一個頁面的狀態(tài)欄和自身相同。

因為這個功能十分通用,所以我們可以通過一個高階組件來完成這件事:

import?React?from?'react'
import?hoistNonReactStatics?from?'hoist-non-react-statics'
import?{?StatusBar?}?from?'react-native'

import?{?isAndroid?}?from?'../../utils/device'

export?const?setStatusBar?=?(statusbarProps?=?{})?=>?WrappedComponent?=>?{??
class?Component?extends?React.PureComponent?{
????constructor(props)?{
??????????super(props)
??????????this._navListener?=?props.navigation.addListener('willFocus',?this._setStatusBar)
????}

????componentWillUnmount()?{
??????????this._navListener.remove();
????}

????_setStatusBar?=?()?=>?{??????
????const?{
????????barStyle?=?"dark-content",
????????backgroundColor?=?'#fff',
????????translucent?=?false
??????}?=?statusbarProps
??????StatusBar.setBarStyle(barStyle)
??????if?(isAndroid())?{
????????StatusBar.setTranslucent(translucent)
????????StatusBar.setBackgroundColor(backgroundColor);
??????}
????}

????render()?
????{??????return?
????}
??}

??return?hoistNonReactStatics(Component,?WrappedComponent);
}

通過裝飾器的方式使用也十分簡單:

@setStatusBar({
??barStyle:?'light-content',
??translucent:?true,??
??backgroundColor:?'transparent'})
??export?default?class?Home?extends?React.PureComponent?{
?...?
}

設(shè)置 Android 全屏且狀態(tài)欄透明

除了在 js 層通過?StatusBar?組件設(shè)置狀態(tài)欄的顏色、半透明等,我們也可以先將 Android 的狀態(tài)欄設(shè)置為全屏且狀態(tài)欄透明,這樣 Android 的表現(xiàn)就和 iOS 一樣,可以統(tǒng)一的去處理。

在?MainActivity.java?中添加下面的代碼,可以設(shè)置全屏且狀態(tài)欄透明:

protected?void?onCreate(Bundle?savedInstanceState)?{????super.onCreate(savedInstanceState);

????View?decorView?=?getWindow().getDecorView();
????decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN?|?View.SYSTEM_UI_FLAG_LAYOUT_STABLE);????if?(Build.VERSION.SDK_INT?>=?21)?{
????????getWindow().setStatusBarColor(Color.TRANSPARENT);
????}
}

設(shè)置完成后的效果如下圖(沒有處理?paddingTop)。

不得不看之React Native 中的狀態(tài)欄

現(xiàn)在 Android 狀態(tài)欄的表現(xiàn)就和 iOS 一樣了,處理的時候統(tǒng)一按照 iOS 的處理邏輯即可,只是在 Header 的高度以及?paddingTop?的計算上不同。

此外,還需要注意?react-native?的 Header 沒有處理 Android 全屏的情況,因此我們需要在 Android 平臺下修改?headerStyle:

defaultNavigationOptions:?{
??headerStyle:?{
????...Platform.OS?===?'android'?&&?{
???????height:?StatusBar.currentHeight?+?44,??????
???????paddingTop:?StatusBar.currentHeight
????}
??}
}

總結(jié)

React Native 中想要讓狀態(tài)欄表現(xiàn)得更好還是需要做一些工作的?,F(xiàn)在看來其實使用?StatusBar?組件更加的容易一點,因為即使在 Android 原生層面設(shè)置了全屏和透明狀態(tài)欄,最后還是需要根據(jù)頁面去設(shè)置狀態(tài)欄內(nèi)容的顏色,所以還不許統(tǒng)一的在 js 層去做,通過高階組件的方式也不是很麻煩。

覺得文章不錯的喜歡的小伙伴可以關(guān)注加轉(zhuǎn)發(fā),歡迎大家前來探討交流,同時,我也非常歡迎大家互相交流技術(shù),共同成長。

另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務(wù)器15元起步,三天無理由+7*72小時售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國服務(wù)器、虛擬主機、免備案服務(wù)器”等云主機租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡單易用、服務(wù)可用性高、性價比高”等特點與優(yōu)勢,專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場景需求。


當(dāng)前文章:不得不看之ReactNative中的狀態(tài)欄-創(chuàng)新互聯(lián)
轉(zhuǎn)載來于:http://weahome.cn/article/dhhids.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部