mirror of
https://github.com/status-im/react-navigation.git
synced 2025-02-24 17:18:09 +00:00
Allow transition configuration between tabs (#2222)
* allow transition configuration between tabs * we don't need to pass configureTransition to TabBarComponent * Update TabAnimations.js * Update TabNavigator.md
This commit is contained in:
parent
3cff180224
commit
0a662c9835
@ -87,6 +87,7 @@ The route configs object is a mapping from route name to a route config, which t
|
|||||||
- `tabBarPosition` - Position of the tab bar, can be `'top'` or `'bottom'`.
|
- `tabBarPosition` - Position of the tab bar, can be `'top'` or `'bottom'`.
|
||||||
- `swipeEnabled` - Whether to allow swiping between tabs.
|
- `swipeEnabled` - Whether to allow swiping between tabs.
|
||||||
- `animationEnabled` - Whether to animate when changing tabs.
|
- `animationEnabled` - Whether to animate when changing tabs.
|
||||||
|
- `configureTransition` - a function that, given `currentTransitionProps` and `nextTransitionProps`, returns a configuration object that describes the animation between tabs.
|
||||||
- `lazy` - Whether to lazily render tabs as needed as opposed to rendering them upfront.
|
- `lazy` - Whether to lazily render tabs as needed as opposed to rendering them upfront.
|
||||||
- `initialLayout` - Optional object containing the initial `height` and `width`, can be passed to prevent the one frame delay in [react-native-tab-view](https://github.com/react-native-community/react-native-tab-view#avoid-one-frame-delay) rendering.
|
- `initialLayout` - Optional object containing the initial `height` and `width`, can be passed to prevent the one frame delay in [react-native-tab-view](https://github.com/react-native-community/react-native-tab-view#avoid-one-frame-delay) rendering.
|
||||||
- `tabBarOptions` - Configure the tab bar, see below.
|
- `tabBarOptions` - Configure the tab bar, see below.
|
||||||
|
@ -25,6 +25,7 @@ import StacksInTabs from './StacksInTabs';
|
|||||||
import StacksOverTabs from './StacksOverTabs';
|
import StacksOverTabs from './StacksOverTabs';
|
||||||
import SimpleStack from './SimpleStack';
|
import SimpleStack from './SimpleStack';
|
||||||
import SimpleTabs from './SimpleTabs';
|
import SimpleTabs from './SimpleTabs';
|
||||||
|
import TabAnimations from './TabAnimations';
|
||||||
|
|
||||||
const ExampleRoutes = {
|
const ExampleRoutes = {
|
||||||
SimpleStack: {
|
SimpleStack: {
|
||||||
@ -90,6 +91,11 @@ const ExampleRoutes = {
|
|||||||
screen: SimpleTabs,
|
screen: SimpleTabs,
|
||||||
path: 'settings',
|
path: 'settings',
|
||||||
},
|
},
|
||||||
|
TabAnimations: {
|
||||||
|
name: 'Animated Tabs Example',
|
||||||
|
description: 'Tab transitions have custom animations',
|
||||||
|
screen: TabAnimations,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
const MainScreen = ({ navigation }) => (
|
const MainScreen = ({ navigation }) => (
|
||||||
|
126
examples/NavigationPlayground/js/TabAnimations.js
Normal file
126
examples/NavigationPlayground/js/TabAnimations.js
Normal file
@ -0,0 +1,126 @@
|
|||||||
|
/**
|
||||||
|
* @flow
|
||||||
|
*/
|
||||||
|
|
||||||
|
import React from 'react';
|
||||||
|
import { Button, ScrollView, Animated } from 'react-native';
|
||||||
|
import { StackNavigator, TabNavigator } from 'react-navigation';
|
||||||
|
|
||||||
|
import Ionicons from 'react-native-vector-icons/Ionicons';
|
||||||
|
import SampleText from './SampleText';
|
||||||
|
|
||||||
|
const MyNavScreen = ({ navigation, banner }) => (
|
||||||
|
<ScrollView>
|
||||||
|
<SampleText>{banner}</SampleText>
|
||||||
|
<Button
|
||||||
|
onPress={() => navigation.navigate('Profile', { name: 'Jordan' })}
|
||||||
|
title="Open profile screen"
|
||||||
|
/>
|
||||||
|
<Button
|
||||||
|
onPress={() => navigation.navigate('NotifSettings')}
|
||||||
|
title="Open notifications screen"
|
||||||
|
/>
|
||||||
|
<Button
|
||||||
|
onPress={() => navigation.navigate('SettingsTab')}
|
||||||
|
title="Go to settings tab"
|
||||||
|
/>
|
||||||
|
<Button onPress={() => navigation.goBack(null)} title="Go back" />
|
||||||
|
</ScrollView>
|
||||||
|
);
|
||||||
|
|
||||||
|
const MyHomeScreen = ({ navigation }) => (
|
||||||
|
<MyNavScreen banner="Home Screen" navigation={navigation} />
|
||||||
|
);
|
||||||
|
|
||||||
|
const MyProfileScreen = ({ navigation }) => (
|
||||||
|
<MyNavScreen
|
||||||
|
banner={`${navigation.state.params.name}s Profile`}
|
||||||
|
navigation={navigation}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
|
||||||
|
const MyNotificationsSettingsScreen = ({ navigation }) => (
|
||||||
|
<MyNavScreen banner="Notifications Screen" navigation={navigation} />
|
||||||
|
);
|
||||||
|
|
||||||
|
const MySettingsScreen = ({ navigation }) => (
|
||||||
|
<MyNavScreen banner="Settings Screen" navigation={navigation} />
|
||||||
|
);
|
||||||
|
|
||||||
|
const MainTab = StackNavigator({
|
||||||
|
Home: {
|
||||||
|
screen: MyHomeScreen,
|
||||||
|
path: '/',
|
||||||
|
navigationOptions: {
|
||||||
|
title: 'Welcome',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Profile: {
|
||||||
|
screen: MyProfileScreen,
|
||||||
|
path: '/people/:name',
|
||||||
|
navigationOptions: ({ navigation }) => ({
|
||||||
|
title: `${navigation.state.params.name}'s Profile!`,
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const SettingsTab = StackNavigator({
|
||||||
|
Settings: {
|
||||||
|
screen: MySettingsScreen,
|
||||||
|
path: '/',
|
||||||
|
navigationOptions: () => ({
|
||||||
|
title: 'Settings',
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
NotifSettings: {
|
||||||
|
screen: MyNotificationsSettingsScreen,
|
||||||
|
navigationOptions: {
|
||||||
|
title: 'Notifications',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const TabAnimations = TabNavigator(
|
||||||
|
{
|
||||||
|
MainTab: {
|
||||||
|
screen: MainTab,
|
||||||
|
path: '/',
|
||||||
|
navigationOptions: {
|
||||||
|
tabBarLabel: 'Home',
|
||||||
|
tabBarIcon: ({ tintColor, focused }) => (
|
||||||
|
<Ionicons
|
||||||
|
name={focused ? 'ios-home' : 'ios-home-outline'}
|
||||||
|
size={26}
|
||||||
|
style={{ color: tintColor }}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
SettingsTab: {
|
||||||
|
screen: SettingsTab,
|
||||||
|
path: '/settings',
|
||||||
|
navigationOptions: {
|
||||||
|
tabBarLabel: 'Settings',
|
||||||
|
tabBarIcon: ({ tintColor, focused }) => (
|
||||||
|
<Ionicons
|
||||||
|
name={focused ? 'ios-settings' : 'ios-settings-outline'}
|
||||||
|
size={26}
|
||||||
|
style={{ color: tintColor }}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
tabBarPosition: 'bottom',
|
||||||
|
animationEnabled: true,
|
||||||
|
configureTransition: (currentTransitionProps,nextTransitionProps) => ({
|
||||||
|
timing: Animated.spring,
|
||||||
|
tension: 1,
|
||||||
|
friction: 35,
|
||||||
|
}),
|
||||||
|
swipeEnabled: false,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
export default TabAnimations;
|
@ -48,6 +48,7 @@ const TabNavigator = (
|
|||||||
tabBarOptions,
|
tabBarOptions,
|
||||||
swipeEnabled,
|
swipeEnabled,
|
||||||
animationEnabled,
|
animationEnabled,
|
||||||
|
configureTransition,
|
||||||
lazy,
|
lazy,
|
||||||
initialLayout,
|
initialLayout,
|
||||||
...tabsConfig
|
...tabsConfig
|
||||||
@ -68,6 +69,7 @@ const TabNavigator = (
|
|||||||
tabBarOptions={tabBarOptions}
|
tabBarOptions={tabBarOptions}
|
||||||
swipeEnabled={swipeEnabled}
|
swipeEnabled={swipeEnabled}
|
||||||
animationEnabled={animationEnabled}
|
animationEnabled={animationEnabled}
|
||||||
|
configureTransition={configureTransition}
|
||||||
lazy={lazy}
|
lazy={lazy}
|
||||||
initialLayout={initialLayout}
|
initialLayout={initialLayout}
|
||||||
/>
|
/>
|
||||||
|
@ -22,6 +22,10 @@ export type TabViewConfig = {
|
|||||||
tabBarOptions?: {},
|
tabBarOptions?: {},
|
||||||
swipeEnabled?: boolean,
|
swipeEnabled?: boolean,
|
||||||
animationEnabled?: boolean,
|
animationEnabled?: boolean,
|
||||||
|
configureTransition?: (
|
||||||
|
currentTransitionProps: Object,
|
||||||
|
nextTransitionProps: Object
|
||||||
|
) => Object,
|
||||||
lazy?: boolean,
|
lazy?: boolean,
|
||||||
initialLayout?: Layout,
|
initialLayout?: Layout,
|
||||||
};
|
};
|
||||||
@ -39,6 +43,10 @@ type Props = {
|
|||||||
tabBarOptions?: {},
|
tabBarOptions?: {},
|
||||||
swipeEnabled?: boolean,
|
swipeEnabled?: boolean,
|
||||||
animationEnabled?: boolean,
|
animationEnabled?: boolean,
|
||||||
|
configureTransition?: (
|
||||||
|
currentTransitionProps: Object,
|
||||||
|
nextTransitionProps: Object
|
||||||
|
) => Object,
|
||||||
lazy?: boolean,
|
lazy?: boolean,
|
||||||
initialLayout: Layout,
|
initialLayout: Layout,
|
||||||
|
|
||||||
@ -162,6 +170,7 @@ class TabView extends React.PureComponent<Props> {
|
|||||||
tabBarComponent,
|
tabBarComponent,
|
||||||
tabBarPosition,
|
tabBarPosition,
|
||||||
animationEnabled,
|
animationEnabled,
|
||||||
|
configureTransition,
|
||||||
swipeEnabled,
|
swipeEnabled,
|
||||||
lazy,
|
lazy,
|
||||||
initialLayout,
|
initialLayout,
|
||||||
@ -189,7 +198,10 @@ class TabView extends React.PureComponent<Props> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (animationEnabled === false && swipeEnabled === false) {
|
if (
|
||||||
|
(animationEnabled === false && swipeEnabled === false) ||
|
||||||
|
typeof configureTransition === 'function'
|
||||||
|
) {
|
||||||
renderPager = this._renderPager;
|
renderPager = this._renderPager;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -197,6 +209,7 @@ class TabView extends React.PureComponent<Props> {
|
|||||||
lazy,
|
lazy,
|
||||||
initialLayout,
|
initialLayout,
|
||||||
animationEnabled,
|
animationEnabled,
|
||||||
|
configureTransition,
|
||||||
swipeEnabled,
|
swipeEnabled,
|
||||||
renderPager,
|
renderPager,
|
||||||
renderHeader,
|
renderHeader,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user