0

我正在开发一个带有Side MenuNavigator的应用程序。在侧边菜单中,有一些菜单项可以让您导航(使用 Navigator),并且菜单项也被设置样式以指示哪个是活动的。

当首先使用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”,但是,“Route TWO”的菜单项没有opacity: 0.5应有的效果(它应该像第三个菜单项一样是半透明的)。

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>
);
4

1 回答 1

0

出现此问题是因为 TouchableHighlight 的子项在按下 TouchableHighlight 后获得默认不透明度 (1)。因为这是一个更具体的问题,所以我在这里提出了一个新问题。

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

于 2017-01-17T09:17:47.230 回答