React Native react-navigation,
1. Introduction to open-source libraries
In January this year, the new open-source react-natvigation library attracted much attention. In less than three months, the number of stars on github has reached 4000 +. The database is recommended for Fb, and Navigator will be deleted in the latest version 0.44 of React Native. React-navigation is said to have a native performance experience. May become the mainstream army of React Native navigation components in the future. This article describes the usage and practical skills of the database based on [^ 1.0.0-beta.9. We can see that although it is a beta version, it is basically stable and can be safely used in the project. React-navigation documentation
This library contains three types of components:
(1) StackNavigator: used to jump to pages and PASS Parameters
(2) TabNavigator: similar to the bottom navigation bar, it is used to switch between different interfaces on the same screen.
(3) DrawerNavigator: slide menu bar for easy screen setting with drawer navigation
Ii. Use react-navigation
The specific content is roughly divided into the following:
(1) react-navigation database attributes
(2) StackNavigator and TabNavigator implement inter-interface jump and Tab Switch
(3) jump between StackNavigator interfaces, pass values, and values
(4) DrawerNavigator implements drawer navigation menu
(5) scalability of DrawerNavigator
(6) custom react-navigation
1. StackNavigator attributes
NavigationOptions: Configure attributes of StackNavigator.
- Title: title. If the title of this navigation bar and the label bar is set to the same, it is not recommended.
- Header: You can set some navigation attributes. If you hide the top navigation bar, set this attribute to null.
- HeaderTitle: Set the title of the navigation bar. Recommended
- HeaderBackTitle: Set the text behind the return arrow on the left of the jump page. It is the title of the previous page by default. It can be customized or set to null.
- HeaderTruncatedBackTitle: when the title of a page does not match the text after the return arrow, it is changed to "return" by default"
- HeaderRight: set the right side of the navigation bar. It can be buttons or other view controls.
- HeaderLeft: Set the left side of the navigation bar. It can be buttons or other view controls.
- HeaderStyle: Set the style of the navigation bar. Background color, high width
- HeaderTitleStyle: Set the text style in the navigation bar
- HeaderBackTitleStyle: Set the 'return' text style in the navigation bar
- HeaderTintColor: Set the color of the navigation bar
- HeaderPressColorAndroid: Android-specific color textures, which must be later than Android 5.0
- GesturesEnabled: whether to support sliding return gestures. It is supported by iOS by default, and disabled by Android by default.
Screen: The corresponding interface name. Enter the page after import.
Mode: defines the jump style
Card: use the default style of iOS and Android
Modal: Unique to iOS, which enables the screen to be drawn from the bottom. Performance similar to iOS present
HeaderMode: Specifies the animation effect when the parent page is returned.
Float: Default iOS Effect
Screen: During the Sliding Process, the whole page will return
None: No animation
CardStyle: Custom jump Effect
- TransitionConfig: Customize the configurations returned by sliding
- OnTransitionStart: The function called when the conversion animation is about to begin
- OnTransitionEnd: the function to be called when the conversion animation is complete
Path: overwrite ing configuration of the path set in the route
InitialRouteName: Set the default page component. It must be a page component registered above.
InitialRouteParams: initial route Parameters
Note: You may not understand the path. The path attribute applies to other apps or browsers that use URLs to open the app and enter the specified page. The path attribute is used to declare an interface path, for example, [/pages/Home ]. In this case, you can enter "app name: // pages/Home" in the mobile browser to start the App and enter the Home page.
2. Introduction to TabNavigator attributes
Screen: The function is the same as that of navigation. It corresponds to the interface name. You can use this screen to pass values and jump to other pages.
NavigationOptions: Configure attributes of TabNavigator
Title: title. The title of the navigation bar and Tab bar are set at the same time.
TabBarVisible: whether to hide the tab bar. Hidden by default (true)
TabBarIcon: Set the icon in the tab bar. You need to set
TabBarLabel: Set the title of the label bar. Recommendation
Navigation bar configuration
TabBarPosition: Set the position of the tabbar. iOS is at the bottom by default, and Android is at the top by default. (Attribute Value: 'top', 'bottom ')
SwipeEnabled: whether to allow sliding between labels
AnimationEnabled: whether to display an animation when changing tags
Lazy: whether to display tags as needed, rather than in advance. This means to load all the tag columns at the bottom when the app is opened. The default value is false. It is recommended to be true.
TrueinitialRouteName: Set the default page component
BackBehavior: press the back key to determine whether to jump to the first Tab (homepage). none indicates not to jump.
TabBarOptions: configure the iOS attributes of the tab bar.
ActiveTintColor: the foreground color of the label and icon is active.
ActiveBackgroundColor: the background color of the label and icon is active.
InactiveTintColor: the foreground color of the label and icon is inactive.
InactiveBackgroundColor: the background color of the label and icon is inactive.
ShowLabel: whether to display the label. style: tabbar is enabled by default.
LabelStyle: Android attribute of the label Style
ActiveTintColor: the foreground color of the label and icon is active.
InactiveTintColor: the foreground color of the label and icon is inactive.
ShowIcon: whether to display the icon. It is disabled by default.
ShowLabel: whether to display the label. style: tabbar is enabled by default.
LabelStyle: label style upperCaseLabel: whether to uppercase the label. The default value is true.
PressColor: the color of the material ripple effect (Android version must be later than 5.0)
PressOpacity: Transparency changes when the tag is pressed (Android version must be smaller than 5.0)
ScrollEnabled: whether to enable the scrolling tab tabStyle: tab Style
IndicatorStyle: The style object of the label indicator (the row at the bottom of the tab ). There will be an extra line at the bottom of Android. You can set the height to 0 to solve this problem temporarily.
LabelStyle: label Style
IconStyle: icon Style
3. Introduction to DrawerNavigator attributes
DrawerNavigatorConfig
- DrawerWidth-drawer width
- The drawerPosition-option is left or right. The default value is left.
- ContentComponent-component used to present the drawer content, such as a navigation item. Navigation of the receiving drawer. The default value is DrawerItems.
- ContentOptions-configure drawer content
InitialRouteName-routeName of the initial route
Order-The routeNames array that defines the sequence of Drawer items.
Path-provides the ing between routeName and path configuration, which overwrites the path set in routeConfigs.
Will the backBehavior-backend button switch to the initial route? If yes, set it to initialRoute; otherwise, set it to none. The default value is initialRoute.
The contentOptions attribute of DrawerItems
- ActiveTintColor-activity tag and Icon color
- ActiveBackgroundColor-background color of the activity tag
- InactiveTintColor-label and Icon color of inactiveTintColor
- InactiveBackgroundColor-background color of the inactive tag
Style object in the content section
LabelStyle-when your label is a string, you must overwrite the style object of the text style in the content section.
I have learned some basic attributes of the three react-navigation components from the above, so we have to pull up our sleeves to witness a miracle.
4. Use StackNavigator + TabNavigator to switch the Tab page and navigate between interfaces.
API definition: StackNavigator (RouteConfigs, StackNavigatorConfig), TabNavigator (RouteConfigs, TabNavigatorConfig)
(1) Integrate react-navigation: Run [npm install react-navigation -- save] on the terminal]
(2) import necessary components on the interface:
import {StackNavigator,TabNavigator,TabBarBottom} from 'react-navigation'; import HomeScreen from './pages/HomePage'; import MineScreen from './pages/MinePage';
(3) define TabNavigator:
Const Tab = TabNavigator ({Home: {screen: HomeScreen, navigationOptions :( {navigation}) => ({tabBarLabel: 'homepage', tabBarIcon :( {focused, tintColor }) => (<TabBarItem tintColor = {tintColor} focused = {focused} normalImage = {require ('. /imgs/nav_fav@2x.png ')} selectedImage = {require ('. /imgs/nav_fav_actived@3x.png ')}/>),}, Mine: {screen: MineScreen, navigationOptions :( {navigation}) => ({tabBarLabel: 'me ', tabBarIcon :( {focused, tintColor}) => (<TabBarItem tintColor = {tintColor} focused = {focused} normalImage = {require ('. /imgs/tab_me_nor@3x.png ')} selectedImage = {require ('. /imgs/tab_me_selected@2x.png ')}/>),},}, {tabBarComponent: TabBarBottom, tabBarPosition: 'bottom', swipeEnabled: false, animationEnabled: false, lazy: true, tabBarOptions: {activeTintColor: '# 06c1ae', inactiveTintColor: '#979797', style: {backgroundColor: '# ffff',}, labelStyle: {fontSize: 20, // text size },}});
TabBarItem is an encapsulated component:
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 } } /> ) } }
We can see that we have defined a TabNavigator navigation component named [Tab. Components are divided into two parameters:
(1) parameters at the first layer define the interface to be switched, that is, the home page and my interface components, which are specified through the screen attribute. You can use the navigationOptions attribute to set relevant property parameters.
(2) set the attribute parameters in the navigation bar.
After TabNavigator is defined, StackNavigator must be used. As the name suggests, StackNavigator stores the entire interface in stack mode, while
TabNavigator is used to switch between different subinterfaces in one interface. So we need to define StackNavigator:
const Navigator = StackNavigator( { Tab:{screen:Tab}, Product:{screen:ProductScreen} }, { navigationOptions:{ headerBackTitle:null, headerTintColor:'#333333', showIcon:true, swipeEnabled:false, animationEnabled:false, }, mode:'card', });
It looks very similar to TabNavigator. It also specifies two parameters:
(1) Specify the interface component to jump. It is also the interface component of the screen attribute identification.
(2) define jump property parameters, that is, some parameter settings and jump methods in the top navigation bar.
We can see that we set the Tab as an interface to StackNavigator. In this way, you can achieve the Tab navigation and jump between interfaces.
Finally, reference StackNavigator in render:
export default class Demo extends Component { render() { return ( <Navigator /> ); } }
StackNavigator also provides the onNavigationStateChange callback method to listen for changes in the navigation status. I will not go into details here. After the interface jump and switch are realized, it is time to increase the feelings between the interfaces to see how to implement the value transfer and value transfer between interfaces.
5. jump between interfaces, pass values, and values
When the interface component is injected into StackNavigator, the interface component is assigned the navigation attribute, that is, the interface component can be obtained through [this. props. navigation] and perform some operations.
The navigation attribute provides a lot of functions to simplify interface operations. The following are some simple examples:
(1) jump between interfaces through the navigate function:
this.props.navigation.navigate('Mine');
The parameter is the name of the interface component we registered at StackNavigator. You can also return to the previous page from the current page:
// Return to the previous page this. props. navigation. goBack ();
(2) When the jump is passed:
This. props. navigation. navigate ('Mine ', {info:' pass the value '});
The first parameter is also the name of the interface component to jump to, and the second parameter is the parameter to be passed. info can be understood as the key, followed by the passed parameter.
(3) obtain the value:
{this.props.navigation.state.params.info}
The transmitted parameters are obtained through state. params, followed by the key value. Info.
After the above implementation is completed, we can have fun ~~ What? I suddenly found that the effect on Android is different from that on IOS. The boss wants the interface to be consistent ~ What should I do? Then we need to make a simple adaptation.
3. DrawerNavigator implement drawer navigation
1. Navigation implementation
API definition: DrawerNavigator (RouteConfigs, DrawerNavigatorConfig)
(1) define DrawerNavigator in the interface:
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);
The definition method is similar to that of StackNavigator.
(2) HomeScreen interface and MineScreen interface:
Export default class HomePage extends Component {static navigationOptions = {drawerLabel: 'homepage', 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)}> click to jump </Text> </View>);} _ skip () {this. props. navigation. navigate ("Mine") ;}} export default class MinePage extends Component {static navigationOptions = {drawerLabel: 'me', 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)}> return to the previous page </Text> </View>);}/*** jump */_ skip () {this. props. navigation. goBack ();}}
The code is very simple, implementing the jump between interfaces.
2. Extended Functions
(1) DrawerView cannot be rolled by default. To implement a scrollable view, you must use the contentComponent custom container, as shown below:
{DrawerWidth: 200, drawer location: "right" contentComponent: props => <ScrollView> <DrawerItems {... props}/> </ScrollView>}
(2) It can overwrite the default components used by navigation and use DrawerItems to customize the navigation components:
import {DrawerItems} from 'react-navigation'; const CustomDrawerContentComponent = (props) => ( <View style = {style.container}> <DrawerItems {... props} /> </View> );
(3) nested drawer navigation
If you nest DrawerNavigation, the drawer is displayed below the parent navigation.
Iv. Custom react-navigation
(1) Adapt to the title of the top navigation bar:
During the test, we found that the title of the title bar on the iphone is in center state, while that on Android is in left-aligned state. So we need to modify the source code for adaptation.
Modify the Code in line 326 of node_modules -- react-navigation -- src -- views -- Header. js to the following:
title: { bottom: 0, left: TITLE_OFFSET, right: TITLE_OFFSET, top: 0, position: 'absolute', alignItems: 'center', }
The above method has some disadvantages by modifying the source code. After all, the scalability is poor. Another way is to set the alignSelf of headerTitleStyle to 'center' in navigationOptions.
(2) remove the text display of the Return key:
Modify the line 91 code of node_modules -- react-navigation -- src -- views -- HeaderBackButton. js to the following.
{Platform.OS === 'ios' && title && <Text onLayout={this._onTextLayout} style={[styles.title, { color: tintColor }]} numberOfLines={1} > {backButtonTitle} </Text>}
Delete the above Code.
(3) dynamically set the header button event:
When we set the left and right buttons in the header, we certainly cannot avoid the Click Event of the button to be set, but there is a problem at this time, navigationOptions is modified to static type, therefore, the onPress method of the button cannot directly use this to call the method in Component. How can this problem be solved? In the official document, the author gives the idea of setting params to dynamically set the header title. In this way, we can pass the click callback function to params as a parameter, and then use navigation in navigationOption to retrieve the settings to onPress:
ComponentDidMount () {/*** will click the callback function as the parameter to pass */this. props. navigation. setParams ({switch: () => this. switchView ()});}
/*** Switch view */switchView () {alert ('failed ')}
Static navigationOptions = ({navigation, screenProps}) => ({headerTitle: 'enterprise service', headerTitleStyle: CommonStyles. headerTitleStyle, headerRight: (<NavigatorItem icon = {Images. ic_navigator} onPress = {() => navigation. state. params. switch ()}/>), headerStyle: CommonStyles. headerStyle });
(4) use BackHandler to process the returned result and click the return key to exit the App twice.
It is not uncommon to click the return key twice to exit the App. I believe many people have encountered many problems when implementing this function in react-navigation. For example, other interfaces cannot be returned. That is, the mobile phone itself intercepts the response before react-navigation. How can we implement react-natigation? We will share with you two implementation methods:
(1) Register BackHandler on the registration page of StackNavigator:
ComponentWillMount () {BackHandler. addEventListener ('hardwarebackpress ', this. _ onBackAndroid);} componentUnWillMount () {BackHandler. addEventListener ('hardwarebackpress ', this. _ onBackAndroid);} _ onBackAndroid = () => {let now = new Date (). getTime (); if (now-lastBackPressed <2500) {return false;} lastBackPressed = now; ToastAndroid. show ('click again to exit application', ToastAndroid. SHORT); return true ;}
(2) Listening to the react-navigation Router
/*** Process Android return key */const defaultStateAction = AppNavigator. router. getStateForAction; AppNavigator. router. getStateForAction = (action, state) =>{ if (state & action. type = NavigationActions. BACK & state. routes. length = 1) {if (lastBackPressed + 2000 <Date. now () {ToastAndroid. show (Constant. hint_exit, ToastAndroid. SHORT); lastBackPressed = Date. now (); const routes = [... state. routes]; return {... state ,... state. routes, index: routes. length-1 ,};}return defastatstateaction (action, state );};
(5) Implement switching between left and right animations on the Android Interface
React-navigation in Android, the default UI switches the animation up and down. How does one implement left-right switching? Simple Configuration:
Copy codeThe Code is as follows:
Import CardStackStyleInterpolator from 'react-navigation/src/views/cardstackstyleinterpolator ';
Then add the following code under the configuration of StackNavigator:
transitionConfig:()=>({ screenInterpolator: CardStackStyleInterpolator.forHorizontal, })
(6) quick click and multiple jumps
When we click jump quickly, multiple repeated interfaces will be opened. How can we solve this problem. In fact, the official git also prompts you to modify the react-navigation source code to solve this problem:
Find the addNavigationHelpers. js file in the scr folder and replace it with the following text:
Export default function <S: *> (navigation: NavigationProp <S, NavigationAction>) {// Add click to judge let debounce = true; return {... navigation, goBack: (key? :? String): boolean => navigation. dispatch (NavigationActions. back ({key: key === undefined? Navigation. state. key: key,}),), navigate: (routeName: string, params?: NavigationParams, action?: NavigationAction,): boolean =>{ if (debounce) {debounce = false; navigation. dispatch (NavigationActions. navigate ({routeName, params, action,}),); setTimeout () =>{ debounce = true ;}, 500,); return true ;}return false ;}, /*** For updating current route params. for example the nav bar title and * buttons are based on the route params. * This means 'setparams' can be used to update nav bar for example. */setParams: (params: NavigationParams): boolean => navigation. dispatch (NavigationActions. setParams ({params, key: navigation. state. key ,}),),};}
V,
Drawer Navigation:
The above are common attributes and skills in practice. The specific operation also requires testing experience in the practice process. I hope it will be helpful for everyone's learning, and I hope you can support the house of helping customers more.