1. <ul id="0c1fb"></ul>

      <noscript id="0c1fb"><video id="0c1fb"></video></noscript>
      <noscript id="0c1fb"><listing id="0c1fb"><thead id="0c1fb"></thead></listing></noscript>

      99热在线精品一区二区三区_国产伦精品一区二区三区女破破_亚洲一区二区三区无码_精品国产欧美日韩另类一区

      RELATEED CONSULTING
      相關(guān)咨詢
      選擇下列產(chǎn)品馬上在線溝通
      服務(wù)時(shí)間:8:30-17:00
      你可能遇到了下面的問題
      關(guān)閉右側(cè)工具欄

      新聞中心

      這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
      不得不看之ReactNative中的狀態(tài)欄-創(chuàng)新互聯(lián)

      預(yù)備知識(shí)

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

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

      iOS 中的狀態(tài)欄

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

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

      Android 中的狀態(tài)欄

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

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

      • 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)用中,每個(gè) Activity 都對(duì)應(yīng)一個(gè)狀態(tài)欄。這意味著,為一個(gè)頁面設(shè)置狀態(tài)欄不會(huì)對(duì)其他頁面的狀態(tài)欄造成影響。

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

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

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

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

      實(shí)際案例

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

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

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

      “主頁”和“我的”頁面使用自定義的 Header,該組件會(huì)根據(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)以下幾點(diǎ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ù)頁面動(dòng)態(tài)的調(diào)整狀態(tài)欄。React Native 為開發(fā)者提供了?StatusBar?組件去控制狀態(tài)欄。

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

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

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

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

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

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

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

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

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

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

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

      因?yàn)檫@個(gè)功能十分通用,所以我們可以通過一個(gè)高階組件來完成這件事:

      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 一樣了,處理的時(shí)候統(tǒng)一按照 iOS 的處理邏輯即可,只是在 Header 的高度以及?paddingTop?的計(jì)算上不同。

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

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

      總結(jié)

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

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

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


      當(dāng)前名稱:不得不看之ReactNative中的狀態(tài)欄-創(chuàng)新互聯(lián)
      文章地址:http://www.ef60e0e.cn/article/dhhids.html
      99热在线精品一区二区三区_国产伦精品一区二区三区女破破_亚洲一区二区三区无码_精品国产欧美日韩另类一区
      1. <ul id="0c1fb"></ul>

        <noscript id="0c1fb"><video id="0c1fb"></video></noscript>
        <noscript id="0c1fb"><listing id="0c1fb"><thead id="0c1fb"></thead></listing></noscript>

        通江县| 海林市| 保康县| 白玉县| 曲水县| 永泰县| 平凉市| 光泽县| 江油市| 齐齐哈尔市| 宜兰县| 峨眉山市| 潞西市| 东丰县| 册亨县| 碌曲县| 专栏| 饶阳县| 黑河市| 渭源县| 城固县| 弥渡县| 都江堰市| 香河县| 科技| 彭州市| 涞水县| 沙河市| 罗甸县| 房产| 尚义县| 亚东县| 彭阳县| 勃利县| 仙居县| 禹州市| 海南省| 昆明市| 涡阳县| 泸溪县| 梁平县|