我一直在尝试为我的反应导航导航器设置主题,这很容易使用硬编码的颜色,即Colours.background
、Colours.accent
。
当用户通过身份验证时,我会提供他们的基本详细信息和主题对象。使用redux(state.auth.user.theme
)将其存储在我的应用程序状态中
我有一个创建导航程序的AppNavigation。
AppNavigation.js
import React from 'react'
import { Text, Animated, Easing, Image, View } from 'react-native'
import { StackNavigator, DrawerNavigator, addNavigationHelpers } from 'react-navigation'
import Icon from 'react-native-vector-icons/EvilIcons'
import { connect } from 'react-redux'
import DrawerContainer from '../Containers/DrawerContainer'
import ScreenTwoScreen from '../Containers/ScreenTwoScreen'
import ScreenOneScreen from '../Containers/ScreenOneScreen'
import DashboardScreen from '../Containers/DashboardScreen'
import LoginScreen from '../Containers/LoginScreen'
import styles from './Styles/NavigationStyles'
import ThemeProvider from '../Themes/ThemeProvider';
import Images from '../Themes/Images';
const Colors = ThemeProvider()
const DrawerStack = DrawerNavigator({
screenOneScreen: { screen: ScreenOneScreen },
dashboardScreen: { screen: DashboardScreen },
}, {
gesturesEnabled: false,
contentComponent: DrawerContainer
})
const drawerButton = (navigation) =>
<Text
style={{ padding: 5, color: 'white' }}
onPress={() => {
// Coming soon: navigation.navigate('DrawerToggle')
// https://github.com/react-community/react-navigation/pull/2492
if (navigation.state.index === 0) {
navigation.navigate('DrawerOpen')
} else {
navigation.navigate('DrawerClose')
}
}
}><Icon name="navicon" color={Colors.headerText} size={24} /></Text>
// login stack
const LoginStack = StackNavigator({
loginScreen: { screen: LoginScreen },
}, {
headerMode: 'none',
navigationOptions: {
}
})
const logoStyle = {
height: 45,
width: 45,
marginLeft: 10,
resizeMode: 'contain'
}
const DrawerNavigation = StackNavigator({
DrawerStack: { screen: DrawerStack }
}, {
headerMode: 'float',
navigationOptions: ({ navigation }) => ({
headerStyle: { backgroundColor: Colors.brand },
title: 'Welcome!',
headerTintColor: Colors.headerText,
gesturesEnabled: false,
headerRight: drawerButton(navigation),
headerLeft: <Image source={Images.clubLogo} style={logoStyle} />
})
})
// Manifest of possible screens
const PrimaryNav = StackNavigator({
loginStack: { screen: LoginStack },
drawerStack: { screen: DrawerNavigation }
}, {
// Default config for all screens
headerMode: 'none',
initialRouteName: 'loginStack',
navigationOptions: {
headerStyle: styles.header
}
})
export default PrimaryNav
这在ReduxNavigation.js:中使用
ReduxNavigation.js
import React from 'react'
import * as ReactNavigation from 'react-navigation';
import { connect } from 'react-redux'
import AppNavigation from './AppNavigation'
import Colors from '../Themes/Colors'
import ThemeProvider from '../Themes/ThemeProvider'
// here is our redux-aware our smart component
class ReduxNavigation extends React.Component {
static navigationOptions = ({ navigation, screenProps }) => {
console.log(navigation)
return {
headerStyle: {
backgroundColor: this.props.user ? this.props.user.club.brand : Colors.brand
}
}
}
render() {
const { dispatch, nav, user } = this.props
const navigation = ReactNavigation.addNavigationHelpers({
dispatch,
state: nav
})
// if (user) {
// theme = ThemeProvider(user.club.theme)
// }
return <AppNavigation navigation={navigation} />
}
}
const mapStateToProps = state => ({ nav: state.nav, user: state.auth.user })
export default connect(mapStateToProps)(ReduxNavigation)
主题提供者.js
没什么特别的:
import Colors from './Colors';
const ThemeProvider = (other ={}) => {
return Object.assign({}, Colors, other)
}
export default ThemeProvider;
我尝试过的东西
- 创建了一个主题提供程序方法,将用户主题合并为颜色,虽然有效,但并不正确
- 将AppNavigation的核心移到了ReduxNavigation中的呈现方法中,但这使得应用程序没有响应,这是可以理解的
- 试图找到一种将主题作为道具传递给PrimaryNav的方法,react导航不喜欢额外的道具
想法和想法?此外,如果有任何用处的话,该应用程序的核心是用InfiniteRed/inite生成的。
找到了一种方法,在ReduxNavigation:中使用screenProps
class ReduxNavigation extends React.Component {
render() {
const { dispatch, nav, user } = this.props
const navigation = ReactNavigation.addNavigationHelpers({
dispatch,
state: nav
})
return <AppNavigation navigation={navigation} screenProps={{ user }} />
}
}
然后在导航器上的AppNavigation中,我需要自定义主题:
DrawerNavigation = StackNavigator({
DrawerStack: { screen: DrawerStack }
}, {
headerMode: 'float',
navigationOptions: ({ navigation, screenProps }) => {
let headerText = Colors.headerText;
let brand = Colors.brand;
let accent = Colors.accent;
if (screenProps.user) {
let theme = screenProps.user.club.theme;
brand = theme.brand;
headerText = theme.headerText;
accent = theme.accent;
}
return ({
headerStyle: { backgroundColor: brand },
title: 'Welcome!',
headerTintColor: headerText,
gesturesEnabled: false,
headerRight: drawerButton(navigation, headerText),
headerLeft: <Image source={Images.clubLogo} style={logoStyle} />
})
}
})