React Native Side菜单中项目缺少样式(应在React Native Navigator中指示活动路径)

时间:2017-01-17 07:49:04

标签: react-native react-native-navigation

我正在使用Side MenuNavigator处理应用。在侧边菜单中,有一些菜单项可让您导航(使用导航器),菜单项也可以设置样式以指示哪一个是活动的。

首次使用navigator.push()转到新路线然后返回navigator.pop()时,与之前有效路线(现在处于非活动状态)对应的菜单项 菜单项的样式(下面完整示例中为RouteMenuItem)如下

style={[
    { padding: 15, borderColor: 'firebrick', borderWidth: 1 },
    (isActive
        ? {backgroundColor: 'green'}
        : {opacity: 0.5}
    )
]}

如何应用{backgroundColor: 'green'}{opacity: 0.5}

下图显示了该错误在Android上的显示方式:" Route ONE"然而,选择"路线TWO"的菜单项。没有opacity: 0.5(它应该像第3个菜单项一样透明)。

react-native-navigator-side-menu-style-bug.png

以下是重现该错误的最小示例的完整代码。组件层次结构如下:

<Navigator renderScene={() => <SideMenu><View /></SideMenu>} />

PS:我们在代码中使用StyleSheet.create(),但在下面的示例中,我刚刚定义了内联样式。它似乎没有任何区别。

import React from 'react';
import {View, Text, TouchableHighlight, Navigator, Dimensions} from 'react-native';
import SideMenu from 'react-native-side-menu';

/***************
/**   Routes   **/
/****************/
const ROUTES = {
    ONE: () => ({ title: 'Route ONE' }),
    TWO: () => ({ title: 'Route TWO' }),
    THREE: () => ({ title: 'Route THREE' }),
};

/**************/
/**   Main   **/
/**************/
export default class Main extends React.Component {
    render() {
        return (
            <Navigator
                style={{flex: 1}}
                initialRouteStack={[
                    ROUTES.ONE(),
                ]}
                renderScene={(route, navigator) =>
                    <Scene route={route} navigator={navigator} />
                }
            />
        );
    }
}

/***************/
/**   Scene   **/
/***************/
class Scene extends React.Component {
    state = {
        menuIsOpen: false,
    }

    openMenu = () => {
        this.setState({ menuIsOpen: true });
    }

    onMenuOpenChanged = (menuIsOpen) => {
        if (this.state.menuIsOpen !== menuIsOpen) {
            this.setState({ menuIsOpen });
        }
    }

    render() {
        const {route, navigator} = this.props;

        return (
            <View style={{flex: 1}}>
                <SideMenu
                    menu={
                        <Menu
                            route={route}
                            navigator={navigator}
                        />
                    }
                    menuPosition="right"
                    bounceBackOnOverdraw={false}
                    onChange={this.onMenuOpenChanged}
                    isOpen={this.state.menuIsOpen}
                    openMenuOffset={Dimensions.get('window').width * 0.75}
                    disableGestures={false}
                >
                    <Screen route={route} navigator={navigator} openMenu={this.openMenu} menuIsOpen={this.state.menuIsOpen} />
                </SideMenu>
            </View>
        );
    }
}

/**************/
/**   Menu   **/
/**************/
class Menu extends React.Component {
    render() {
        const {route, navigator} = this.props;

        return (
            <View style={{ flex: 1, backgroundColor: 'coral', paddingTop: 25 }}>
                <Text>Currently at {route.title}</Text>
                <RouteMenuItem forRoute={ROUTES.ONE()} route={route} navigator={navigator} />
                <RouteMenuItem forRoute={ROUTES.TWO()} route={route} navigator={navigator} />
                <RouteMenuItem forRoute={ROUTES.THREE()} route={route} navigator={navigator} />
            </View>
        );
    }
}

const RouteMenuItem = ({forRoute, route, navigator}) => (
    <TouchableHighlight onPress={() => navigator.push(forRoute)}>
        <Text style={[ { padding: 15, borderColor: 'firebrick', borderWidth: 1 }, (forRoute.title === route.title ? {backgroundColor: 'green'} : {opacity: 0.5}) ]}>
            Go to {forRoute.title} ({(forRoute.title === route.title ? 'current route' : 'NOT CURRENT ROUTE')})
        </Text>
    </TouchableHighlight>
);

/*****************************/
/**   Screen, inside Menu   **/
/*****************************/
class Screen extends React.Component {
    render() {
        const {route, navigator, openMenu, menuIsOpen} = this.props;

        return (
            <View style={{ flex: 1 }}>
                <View style={{  flexDirection: 'row', justifyContent: 'space-between', backgroundColor: 'peachpuff', paddingTop: 25 }}>
                    <HeaderButton onPress={navigator.pop}>Back</HeaderButton>
                    <HeaderButton onPress={openMenu}>Menu</HeaderButton>
                </View>
                <View style={{ flex: 1, backgroundColor: 'white' }}>
                    <Text style={{ margin: 50, fontSize: 50 }}>
                        {route.title}
                    </Text>
                </View>
            </View>
        );
    }
}

const HeaderButton = ({onPress, children}) => (
    <TouchableHighlight underlayColor="green" onPress={onPress}>
        <Text style={{ padding: 10, borderColor: 'firebrick', borderWidth: 1 }}>
            {children}
        </Text>
    </TouchableHighlight>
);

1 个答案:

答案 0 :(得分:0)

问题出现是因为TouchableHighlight的孩子在按下TouchableHighlight后会获得默认的不透明度(1)。由于这是一个更具体的问题,我已经提出了一个新问题here

在这种情况下,当返回到前一个路径时会出现错误,因为Menu的该实例中的菜单项被按下了(在我们发现错误之前将我们移动到新路线)。