react-navigation 使用詳解

来源:http://www.cnblogs.com/gdsblog/archive/2017/08/14/7358400.html
-Advertisement-
Play Games

另一個大嬸寫的關於抽屜的博文: http://blog.csdn.net/lu1024188315/article/details/73608616 今天參考大灰狼得博客,好好得總結一下navigation得用法。以前總是看官方文檔,但理解得不太透測。 一、開源庫介紹 今年1月份,新開源的React ...




 另一個大嬸寫的關於抽屜的博文: http://blog.csdn.net/lu1024188315/article/details/73608616

今天參考大灰狼得博客,好好得總結一下navigation得用法。以前總是看官方文檔,但理解得不太透測。

一、開源庫介紹

 

 

今年1月份,新開源的React-natvigation庫備受矚目。在短短不到3個月的時間,github上星數已達4000+。Fb推薦使用庫,並且在React Native當前最新版本0.44中將Navigator刪除。react-navigation據稱有原生般的性能體驗效果。可能會成為未來React Native導航組件的主流軍。本篇內容基於【 ^1.0.0-beta.9 】版本來介紹關於該庫的使用和實戰技巧。可以看到,雖然是beta版本,不過基本穩定,大家可放心在項目中使用。該庫包含三類組件:

(1)StackNavigator:用來跳轉頁面和傳遞參數

(2)TabNavigator:類似底部導航欄,用來在同一屏幕下切換不同界面

(3)DrawerNavigator:側滑菜單導航欄,用於輕鬆設置帶抽屜導航的屏幕


二、react-navigation使用


具體內容大致分為如下:

(1)react-navigation庫屬性介紹

(2)StackNavigator、TabNavigator實現界面間跳轉,Tab切換

(3)StackNavigator界面間跳轉、傳值、取值

(4)DrawerNavigator實現抽屜導航菜單

(5)DrawerNavigator擴展功能

(6)修改源碼,定製UI界面


1、StackNavigator屬性介紹

 navigationOptions:配置StackNavigator的一些屬性。  
  
    title:標題,如果設置了這個導航欄和標簽欄的title就會變成一樣的,不推薦使用  
    header:可以設置一些導航的屬性,如果隱藏頂部導航欄只要將這個屬性設置為null  
    headerTitle:設置導航欄標題,推薦  
    headerBackTitle:設置跳轉頁面左側返回箭頭後面的文字,預設是上一個頁面的標題。可以自定義,也可以設置為null  
    headerTruncatedBackTitle:設置當上個頁面標題不符合返回箭頭後的文字時,預設改成"返回"  
    headerRight:設置導航條右側。可以是按鈕或者其他視圖控制項  
    headerLeft:設置導航條左側。可以是按鈕或者其他視圖控制項  
    headerStyle:設置導航條的樣式。背景色,寬高等  
    headerTitleStyle:設置導航欄文字樣式  
    headerBackTitleStyle:設置導航欄‘返回’文字樣式  
    headerTintColor:設置導航欄顏色  
    headerPressColorAndroid:安卓獨有的設置顏色紋理,需要安卓版本大於5.0  
    gesturesEnabled:是否支持滑動返回手勢,iOS預設支持,安卓預設關閉  
   
  
screen:對應界面名稱,需要填入import之後的頁面  
  
mode:定義跳轉風格  
  
   card:使用iOS和安卓預設的風格  
  
   modal:iOS獨有的使屏幕從底部畫出。類似iOS的present效果  
  
headerMode:返回上級頁面時動畫效果  
  
   float:iOS預設的效果  
  
   screen:滑動過程中,整個頁面都會返回  
  
   none:無動畫  
  
cardStyle:自定義設置跳轉效果  
  
   transitionConfig: 自定義設置滑動返回的配置  
  
   onTransitionStart:當轉換動畫即將開始時被調用的功能  
  
   onTransitionEnd:當轉換動畫完成,將被調用的功能  
  
path:路由中設置的路徑的覆蓋映射配置  
  
initialRouteName:設置預設的頁面組件,必須是上面已註冊的頁面組件  
  
initialRouteParams:初始路由參數 

註:大家可能對於path不太理解。path屬性適用於其他app或瀏覽器使用url打開本app併進入指定頁面。path屬性用於聲明一個界面路徑,例如:【/pages/Home】。此時我們可以在手機瀏覽器中輸入:app名稱://pages/Home來啟動該App,併進入Home界面。

2、TabNavigator屬性介紹

 screen:和導航的功能是一樣的,對應界面名稱,可以在其他頁面通過這個screen傳值和跳轉。  
  
  
navigationOptions:配置TabNavigator的一些屬性  
  
title:標題,會同時設置導航條和標簽欄的title  
  
tabBarVisible:是否隱藏標簽欄。預設不隱藏(true)  
  
tabBarIcon:設置標簽欄的圖標。需要給每個都設置  
  
tabBarLabel:設置標簽欄的title。推薦  
  
導航欄配置  
  
tabBarPosition:設置tabbar的位置,iOS預設在底部,安卓預設在頂部。(屬性值:'top''bottom')  
  
swipeEnabled:是否允許在標簽之間進行滑動  
  
animationEnabled:是否在更改標簽時顯示動畫  
  
lazy:是否根據需要懶惰呈現標簽,而不是提前,意思是在app打開的時候將底部標簽欄全部載入,預設false,推薦為true  
  
trueinitialRouteName: 設置預設的頁面組件  
  
backBehavior:按 back 鍵是否跳轉到第一個Tab(首頁), none 為不跳轉  
  
tabBarOptions:配置標簽欄的一些屬性iOS屬性  
  
activeTintColor:label和icon的前景色 活躍狀態下  
  
activeBackgroundColor:label和icon的背景色 活躍狀態下  
  
inactiveTintColor:label和icon的前景色 不活躍狀態下  
  
inactiveBackgroundColor:label和icon的背景色 不活躍狀態下  
  
showLabel:是否顯示label,預設開啟 style:tabbar的樣式  
  
labelStyle:label的樣式安卓屬性  
  
activeTintColor:label和icon的前景色 活躍狀態下  
  
inactiveTintColor:label和icon的前景色 不活躍狀態下  
  
showIcon:是否顯示圖標,預設關閉  
  
showLabel:是否顯示label,預設開啟 style:tabbar的樣式  
  
labelStyle:label的樣式 upperCaseLabel:是否使標簽大寫,預設為true  
  
pressColor:material漣漪效果的顏色(安卓版本需要大於5.0)  
  
pressOpacity:按壓標簽的透明度變化(安卓版本需要小於5.0)  
  
scrollEnabled:是否啟用可滾動選項卡 tabStyle:tab的樣式  
  
indicatorStyle:標簽指示器的樣式對象(選項卡底部的行)。安卓底部會多出一條線,可以將height設置為0來暫時解決這個問題  
  
labelStyle:label的樣式  
  
iconStyle:圖標樣式 

3、DrawerNavigator屬性介紹

    DrawerNavigatorConfig  
      
        drawerWidth - 抽屜的寬度  
        drawerPosition - 選項是左或右。 預設為左側位置  
        contentComponent - 用於呈現抽屜內容的組件,例如導航項。 接收抽屜的導航。 預設為DrawerItems  
        contentOptions - 配置抽屜內容  
      
        initialRouteName - 初始路由的routeName  
        order - 定義抽屜項目順序的routeNames數組。  
        路徑 - 提供routeName到路徑配置的映射,它覆蓋routeConfigs中設置的路徑。  
        backBehavior - 後退按鈕是否會切換到初始路由? 如果是,設置為initialRoute,否則為none。 預設為initialRoute行為  
      
       DrawerItems的contentOptions屬性  
      
        activeTintColor - 活動標簽的標簽和圖標顏色  
        activeBackgroundColor - 活動標簽的背景顏色  
        inactiveTintColor - 非活動標簽的標簽和圖標顏色  
        inactiveBackgroundColor - 非活動標簽的背景顏色  
        內容部分的樣式樣式對象  
        labelStyle - 當您的標簽是字元串時,要覆蓋內容部分中的文本樣式的樣式對象  

從上述中大致瞭解了react-navigation三種組件的一些基本屬性,所以到我們甩起袖子擼代碼見證下奇跡了。

4、使用StackNavigator + TabNavigator實現Tab界面切換、界面間導航

 


API定義:StackNavigator(RouteConfigs, StackNavigatorConfig)、TabNavigator(RouteConfigs, TabNavigatorConfig)

(1)集成 react-navigation:在終端執行 【 npm install react-navigation --save 】

(2)界面中導入必要組件:

    import {StackNavigator,TabNavigator,TabBarBottom} from 'react-navigation';  
    import HomeScreen from './pages/HomePage';  
    import MineScreen from './pages/MinePage';  

(3)定義TabNavigator:

 

 const Tab = TabNavigator(  
  {  
    Home:{  
      screen:HomeScreen,  
      navigationOptions:({navigation}) => ({  
        tabBarLabel:'首頁',  
        tabBarIcon:({focused,tintColor}) => (  
          <TabBarItem  
            tintColor={tintColor}  
            focused={focused}  
            normalImage={require('./imgs/[email protected]')}  
            selectedImage={require('./imgs/[email protected]')}  
          />  
        )  
      }),  
    },  
  
    Mine:{  
          screen:MineScreen,  
          navigationOptions:({navigation}) => ({  
          tabBarLabel:'',  
          tabBarIcon:({focused,tintColor}) => (  
            <TabBarItem  
             tintColor={tintColor}  
              focused={focused}  
              normalImage={require('./imgs/[email protected]')}  
              selectedImage={require('./imgs/[email protected]')}  
            />  
          )  
        }),  
      },  
    },  
  
    {  
      tabBarComponent:TabBarBottom,  
      tabBarPosition:'bottom',  
      swipeEnabled:false,  
      animationEnabled:false,  
      lazy:true,  
      tabBarOptions:{  
        activeTintColor:'#06c1ae',  
        inactiveTintColor:'#979797',  
        style:{backgroundColor:'#ffffff',},  
        labelStyle: {  
              fontSize: 20, // 文字大小  
          },  
      }  
        
    }  
  
  ); 

 

TabBarItem為封裝的組件:

 

    import React,{Component} from 'react';  
    import {Image} from 'react-native';  
      
    export default class TabBarItem extends Component {  
      
        render() {  
            return(  
                <Image source={ this.props.focused ? this.props.selectedImage : this.props.normalImage }  
                    style={ { tintColor:this.props.tintColor,width:25,height:25 } }  
                />  
            )  
        }  
          
    }  

 

 

 

可以看到,我們定義了一個名稱為【Tab】的TabNavigator的導航組件。在組件中,分為兩層參數:

(1)第一層參數定義了要切換的界面,即【首頁】、【我】兩個界面組件,通過screen屬性指定。並且通過navigationOptions屬性設置相關屬性參數。

(2)設置導航欄的屬性參數。

TabNavigator定義好之後,需要用StackNavigator,顧名思義,StackNavigator就是以棧的方式來存放整個界面的,而TabNavigator是作為一個界面內不同子界面之間切換。所以還需要我們定義StackNavigator:

    const Navigator = StackNavigator(  
        
      {  
        Tab:{screen:Tab},  
        Product:{screen:ProductScreen}  
      },  
      
      {  
        navigationOptions:{  
          headerBackTitle:null,  
          headerTintColor:'#333333',  
          showIcon:true,  
         swipeEnabled:false,  
         animationEnabled:false,  
        },  
      
        mode:'card',  
      });  

看起來和TabNavigator很相似,同樣是指定了兩個參數:

(1)指定要跳轉的界面組件。同樣是screen屬性標識界面組件,不多贅述。

(2)定義跳轉屬性參數,即頂部導航欄的一些參數設置和跳轉方式。

可以看到,我們將Tab作為一個界面設置到了StackNavigator。這樣就可以實現Tab導航和界面間跳轉的效果了。

最後就是在render中引用StackNavigator:

 

 export default class Demo extends Component {  
  
  render() {  
        return (  
          <Navigator />  
        );  
  }  
} 

 

StackNavigator還提供了onNavigationStateChange回調方法,用來監聽導航狀態的改變。具體不再贅述。實現了界面跳轉和切換,那麼就該來增加下界面之間的感情了,來看看如何實現界面之間的傳值和取值。

5、界面間跳轉、傳值、取值
在界面組件註入到StackNavigator中時,界面組件就被賦予了navigation屬性,即在界面組件中可以通過【this.props.navigation】獲取併進行一些操作。

navigation屬性中提供了很多的函數簡化界面間操作,簡單列舉幾點:

(1)通過navigate函數實現界面之間跳轉:

 

this.props.navigation.navigate('Mine');  

 

參數為我們在StackNavigator註冊界面組件時的名稱。同樣也可以從當前頁面返回到上一頁:

 

    // 返回上一頁  
    this.props.navigation.goBack();  

 

(2)跳轉時傳值:

 

this.props.navigation.navigate('Mine',{info:'傳值過去'});  

 

第一個參數同樣為要跳轉的界面組件名稱,第二個參數為要傳遞的參數,info可以理解為key,後面即傳遞的參數。

 

(3)獲取值:

 

{this.props.navigation.state.params.info}  

 

通過state.params來獲取傳來的參數,後面為key值。此處為info。

以上實現完成,我們就可以愉快的玩耍啦~~ 什麼?忽然發現在Android上的效果和IOS效果不一樣。老闆要界面一致哇~ 怎麼辦?那就需要我們進行簡單的適配了。

 

三、DrawerNavigator實現抽屜導航


1、導航實現

API定義:DrawerNavigator(RouteConfigs,DrawerNavigatorConfig)

(1)界面中定義DrawerNavigator:

    import {StackNavigator,TabNavigator,DrawerNavigator} from 'react-navigation';  
    import HomeScreen from './pages/HomePage';  
    import MineScreen from './pages/MinePage';  
      
    export default class Demo extends Component {  
      
      render() {  
            return (  
              <Navigator />  
            );  
      }  
    }  
      
    const Navigator = DrawerNavigator({  
      
        Home:{screen:HomeScreen},  
        Mine:{screen:MineScreen},  
    });  
      
    const styles = StyleSheet.create({  
      
        container: {  
            flex: 1,  
        },  
    });  
      
    AppRegistry.registerComponent('Demo', () => Demo);  

 

定義方式和StackNavigator基本類似,不再贅述。

(2)HomeScreen界面和MineScreen界面:

 

    export default class HomePage extends Component {  
      
        static navigationOptions = {  
            drawerLabel: '首頁',  
            drawerIcon:({tintColor}) => (  
                <Image  
                    source={require('./../imgs/ic_happy.png')}  
                    style={[styles.icon, {tintColor: tintColor}]}/>  
            ),  
        };  
      
        render() {  
            return(  
                <View style={{flex:1}}>  
                    <Text onPress={this._skip.bind(this)}>點擊跳轉</Text>  
                </View>  
            );  
        }  
      
        _skip() {  
            this.props.navigation.navigate("Mine");  
        }  
    }  
      
      
    export default class MinePage extends Component {  
      
        static navigationOptions = {  
            drawerLabel:'',  
             drawerIcon: ({ tintColor }) => (  
                <Image  
                    source={require('./../imgs/ic_h.png')}  
                    style={[styles.icon, {tintColor: tintColor}]}  
                />  
            ),  
        };  
      
        render() {  
            return(  
                <View style={{flex:1}}>  
                    <Text onPress={this._skip.bind(this)}>返回上一界面</Text>  
                </View>  
            );  
        }  
      
        /**  
         * 跳轉  
         */  
        _skip() {  
            this.props.navigation.goBack();  
        }  
    }  

 

代碼很簡單,實現了界面之間的跳轉。

2、擴展功能

(1)預設DrawerView不可滾動。要實現可滾動視圖,必須使用contentComponent自定義容器,如下所示:

 

    {  
      drawerWidth:200,  
      抽屜位置:“對”  
      contentComponent:props => <ScrollView> <DrawerItems {... props} /> </ ScrollView>  
    }  

 

(2)可以覆蓋導航使用的預設組件,使用DrawerItems自定義導航組件:

 

    import {DrawerItems} from 'react-navigation';  
      
    const CustomDrawerContentComponent = (props) => (  
      <View style = {style.container}>  
        <DrawerItems {... props} />  
      </View>    
    );  

 

(3)嵌套抽屜導航
如果您嵌套DrawerNavigation,抽屜將顯示在父導航下方。

 

四、react-navigation源碼定製


(1)適配頂部導航欄標題:

 測試中發現,在iphone上標題欄的標題為居中狀態,而在Android上則是居左對齊。所以需要我們修改源碼,進行適配。

【node_modules -- react-navigation -- src -- views -- Header.js】的326行代碼處,修改為如下:

 

 title: {  
   bottom: 0,  
   left: TITLE_OFFSET,  
   right: TITLE_OFFSET,  
   top: 0,  
   position: 'absolute',  
   alignItems: 'center',  
 } 

(2)去除返回鍵文字顯示:

【node_modules -- react-navigation -- src -- views -- HeaderBackButton.js】的91行代碼處,修改為如下即可。

 

 {Platform.OS === 'ios' &&  
     title &&  
     <Text  
       onLayout={this._onTextLayout}  
       style={[styles.title, { color: tintColor }]}  
       numberOfLines={1}  
     >  
       {backButtonTitle}  
     </Text>} 

 

將上述代碼刪除即可。

(3)設置標題欄的按鈕單擊事件:

因為在界面組件中設置標題參數時,需要將navigationOptions定義成static。所以我們不能直接通過this.xxx.bind(this)來調用自定義函數,怎麼辦呢?可以通過如何方式解決:

 

    class demo extends Component {  
      
        static navigationOptions =({navigation})=>({  
                right:( <Button  onPress={state.params.clickParams}/>)  
        })  
        _btnClick=()=> {  
         alert('單擊')  
        };  
        componentWillMount() {  
           this.props.navigation.setParams({clickParams:this._btnClick})  
        }  
    }  

 

(4)動態設置標題欄顯示和隱藏

根據(3)中的思想,我們可以利用setParams來動態修改狀態欄的顯示和隱藏:

 

    class demo extends Component {  
        static navigationOptions = ({navigation}) =>({  
               visible: state.params.headerState ,  
        });  
      
        render(){  
            return(  
                <Button  
                title="Hide Header"  
                onPress={() => this.props.navigation.setParams({ headerState : 'none' })}  
            />)  
        }  
    }  

 

五、效果圖

 


抽屜導航:

 

 

 

 



 

這篇文章真心值得收藏!+點贊+分享!!!

 

 

 

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 產品終於上線,後期主要是優化了。在開發過程中用到了很多location對象的知識,趁現在有時間先整理一下。 Location 對象存儲在 Window 對象的 Location 屬性中,可通過window.location對其訪問,表示那個視窗中當前顯示的文檔的 Web 地址。它的 href 屬性存 ...
  • 本系列課程選用vue的版本為1.0.21, 什麼是vue? vue是由尤雨溪開發的一款基於MVVM的框架,M->模型,V->視圖, 也就是說模型數據改變了,視圖也跟著改變, 視圖內容改變,模型內容也跟著改變, 業界稱之為雙向綁定,或者說雙向數據驅動,基於此特點,學習這個框架,跟jquery完全不同, ...
  • 本文為純理論文章,沒有 Demo,沒有配圖,可能會略微枯燥。 大家都知道,position:fixed 在日常的頁面佈局中非常常用,在許多佈局中起到了關鍵的作用。它的作用是: position:fixed 的元素將相對於屏幕視口(viewport)的位置來指定其位置。並且元素的位置在屏幕滾動時不會改 ...
  • 一、在ES5中存在6中數據類型 基本數據類型:undefined,null,boolean,string ,number 引用數據類型:Object 在ES6中引入新的數據類型(第七種):Symbol 二、作為屬性名的Symbol。 ...
  • Spinner使用一 一、使用方法 1、在layout中創建Spinner控制項 <Spinner android:id="@+id/spinner1" android:layout_width="match_parent" android:layout_height="wrap_content" / ...
  • 首先你要花點時間針對objective-c語言的學習;畢竟這個是iOS開發的基礎(你也可以嘗試用Swift,但此項目只是針對OC),編程套路其實都是差不多,多寫多想多實踐;關於環境的搭建就不在本文進行介紹,這部分內容可以自行百度或谷歌,都有相應的說明; 對於一個剛入門總是希望有個完整的項目可以直接運 ...
  • 原生的,也不知道會不會用到,以前的筆記。 文件夾管理 1、拿到文件管理者單例 2、使用管理者創建文件夾 3、創建文件 4、讀取文件信息 5、讀取文件返回的字典信息 6、文件讀取 6-1)、方法1: 6-2)、方法2: 7、文件移動(剪切、重命名) 8、文件複製 9、文件刪除 文件操作 ...
  • iOS雖然也有SQL,不過用得少(至少我目前是這樣)。大數據直接丟給後臺,小的用Plist足矣。 再退一步,有FMDB,原生的也用得少了。 下麵是之前學SQL時候的筆記。 1、創建 1-1)、打開: 資料庫指針、保存地址 1-2)、創建: 資料庫指針、創建指令、錯誤指令 1-3)、關閉: 資料庫指針 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...