React-Navigation 入门到高阶使用
对于新手入坑React-Native,可能搭建项目没有好用的脚手架会浪费很多的时间在查找,尝试和验证,例如react-navigation,必备但是又不需要精研的组件,那么接下来你想要的都会有:
React-Navigation 官网直通车,对于新手使用,我只说关键的地方
话不多说,在你的项目里install package
npm install react-navigation
npm install react-native-reanimated react-native-gesture-handler react-native-screens react-native-safe-area-context @react-native-community/masked-view
在强调一次,React-Native版本>= 0.60 会自动linking,
否则需要你手动去linking,官网都有说明:
React-Native >= 0.60
cd ios
pod install
React-Native < 0.60, 还需要:
react-native link react-native-reanimated
react-native link react-native-gesture-handler
react-native link react-native-screens
react-native link react-native-safe-area-context
下面的图你会看到auto-lingk...
当然针对你的项目andoridx,你还需要jetifier
npm install --save-dev jetifier
在package.json中
"scripts": {
"postinstall": "jetifier -r"
}
默认你的React-Native已经升级0.60及以上,运行脚本
npm run postinstall
在MainActivity.java中
package com.reactnavigation.example;
import com.facebook.react.ReactActivity;
+ import com.facebook.react.ReactActivityDelegate;
+ import com.facebook.react.ReactRootView;
+ import com.swmansion.gesturehandler.react.RNGestureHandlerEnabledRootView;
public class MainActivity extends ReactActivity {
@Override
protected String getMainComponentName() {
return "Example";
}
+ @Override
+ protected ReactActivityDelegate createReactActivityDelegate() {
+ return new ReactActivityDelegate(this, getMainComponentName()) {
+ @Override
+ protected ReactRootView createRootView() {
+ return new RNGestureHandlerEnabledRootView(MainActivity.this);
+ }
+ };
+ }
}
在使用的地方(app.js或index.js)引入头文件即可
import 'react-native-gesture-handler';
那现在准备工作已经OK了,其实准备工作和官网无差别,接下来是如何无衔接的使用stackNavigator和BottomTabNavigator。
官网中说createBottomTabNavigator有routes和config,
- routes是设置单一界面,里面的navigationOptions设置的是tabBar的所有属性:如title,tabBarIcon,tabBarIcon,tabBarOnPress...等等。
tabBarIcon中自有:
{ focused: boolean, horizontal: boolean, tintColor: string }
focused: 是否被选择
horizontal:是否旋转手机
tintColor:选择的颜色
tabBarOnPress当tabBar选择要继承defaultHandler,否则会无效:
({navigation, defaultHandler}) => {
defaultHandler()
},
- config是tabBar的统一设置,如initialRouteName,初始加载route,tabBarOptions设置的一些属性,官网都有说明,简单说几个常用的:activeTintColor,被点击的颜色;labelStyle,名称设置;style:tabBar约束设置。
具体使用如下:
const tabNavigator = createBottomTabNavigator(
{
Home: {
screen: TTHomeScreen,
navigationOptions: {
tabBarIcon: ({focused, tintColor}) => (
<Image source={focused ? require('../image/home.png') : require('../image/unHome.png')}
style={{width: 25, height: 25}}/>
),
tabBarOnPress: ({navigation, defaultHandler}) => {
defaultHandler()
console.log(navigation.state.routeName)
},
}
},
Car: {
screen: TTCarScreen,
navigationOptions: {
tabBarIcon: ({focused, tintColor}) => (
<Image source={focused ? require('../image/car.png') : require('../image/unCar.png')}
style={{width: 25, height: 25}}/>
),
tabBarOnPress: ({navigation, defaultHandler}) => {
defaultHandler()
console.log(navigation.state.routeName)
}
}
},
Mine: {
screen: TTMineScreen,
navigationOptions: {
tabBarIcon: ({focused, tintColor}) => (
<Image source={focused ? require('../image/mine.png') : require('../image/unMine.png')}
style={{width: 25, height: 25}}/>
),
tabBarOnPress: ({navigation, defaultHandler}) => {
defaultHandler()
console.log(navigation.state.routeName)
}
}
},
Settings: {
screen: TTSettingScreen,
navigationOptions: {
tabBarIcon: ({focused, tintColor}) => (
<Image source={focused ? require('../image/set.png') : require('../image/unSet.png')}
style={{width: 25, height: 25}}/>
),
tabBarOnPress: ({navigation, defaultHandler}) => {
defaultHandler()
console.log(navigation.state.routeName)
},
}
}
},
{
/* Other configuration remains unchanged */
tabBarOptions: {
activeTintColor: '#e91e63',
labelStyle: {
fontSize: 14,
},
style: {
backgroundColor: 'white',
},
},
}
);
设置完这些你会发现,缺少设置stackNavitor,也没有跳转路由,
先来设置路由类
创建一个新的类TTStackRouter
const NavigatorScreen = {
TTHomeDetailScreen: {
screen: TTHomeDetailScreen,
navigationOptions:{
title: '详情'
}
},
<!--可以添加更多的跳转类,如TTHomeDetailScreen-->
}
export default NavigatorScreen;
把刚刚的tabNavigator添加进来,
属性设置在项目中自行参考是否需要
<!--navigator设置后面都有具体描述可以参考-->
NavigatorScreen.mainScreen = {
screen: tabNavigator,
navigationOptions: {
// headerShown: false, // 隐藏header
headerStyle: {
elevation: 0, // 移除 Android Header 阴影
shadowOpacity: 0, // 移除 iOS Header 阴影
},
headerTitleAlign: 'center', // Android 标题居中
headerBackTitleVisible: false, // 隐藏 iOS 返回按钮标题
headerPressColorAndroid: 'transparent', // 移除 Android 点击返回按钮效果
cardStyleInterpolator: CardStyleInterpolators.forHorizontalIOS, // 切换路由时水平动画
headerStyleInterpolator: HeaderStyleInterpolators.forUIKit, // 切换路时 Header 动画
},
};
路由配置好了,使用的时候会发现,navigator的routerName都是mainScreen,现在去为每个模块配置routerName
// 给tabNavigator添加headerTitle
tabNavigator.navigationOptions = ({ navigation }) => {
const { routeName } = navigation.state.routes[navigation.state.index];
// You can do whatever you like here to pick the title based on the route name
const headerTitle = routeName;
return {
headerTitle,
};
};
最后配置stackNavigator,并输出creatAppContainer,到现在完成了react-navigation的简单项目配置
const mainScreenStack = createStackNavigator(NavigatorScreen, {
initialRouteName: 'mainScreen',
defaultNavigationOptions: {
headerBackTitleVisible: false, // 隐藏 iOS 返回按钮标题
}
});
const AppContainer = createAppContainer(mainScreenStack);
export default AppContainer;