TabNavigator 仅显示第一个选项卡

TabNavigator only showing first tab

我正在使用 RN 开发一个新应用程序并使用来自 react-navigation 库的 TabNavigator,TabNavigator 的最基本示例仅显示第一个选项卡。我在某处读到它可能是一个错误,可以通过将 react-navigation 降级到 1.0.3 来解决,但它对我不起作用。如何解决?

tab1 tab2

app.js

import React, { Component } from 'react';
import Dashboard from './screens/Dashboard';
import Profile from './screens/Profile';
// import {I18nManager} from 'react-native';
// import { Container, Header, Content, Footer, FooterTab, Button, Icon, Text, Badge, Tab, Tabs } from 'native-base';
import { TabNavigator, TabBarBottom } from 'react-navigation';
import Ionicons from 'react-native-vector-icons/Ionicons';

export default TabNavigator({
    home: { screen: Dashboard },
    profile: { screen: Profile },
    nav: { screen: Dashboard },
},

{
    navigationOptions: ({ navigation }) => ({
        tabBarIcon: ({ focused, tintColor }) => {
            const { routeName } = navigation.state;
            let iconName;
            if (routeName === 'home') {
                iconName = `ios-pulse${focused ? '' : '-outline'}`;
            } else if (routeName === 'profile') {
                iconName = `ios-person${focused ? '' : '-outline'}`;
            }
            // You can return any component that you like here! We usually use an
            // icon component from react-native-vector-icons
            return <Ionicons name={iconName} size={25} color={tintColor} />;
        },
    }),
    tabBarOptions: {
        activeTintColor: 'blue',
        inactiveTintColor: 'gray',
    },
    tabBarComponent: TabBarBottom,
    lazy: false,
    tabBarPosition: 'bottom',
    animationEnabled: false,
    swipeEnabled: false,
}
);

Dashboard.js

import React, { Component } from 'react';
import { TouchableOpacity,
    Title,
    Subtitle,
    Tile,
    Divider,
    ImageBackground,
    Card,
    Image,
    View,
    Caption,
    GridRow,
    ListView,
    Screen
} from '@shoutem/ui';
// import I18n from 'react-native-i18n';
// import {I18nManager} from 'react-native';
//          I18nManager.forceRTL(true);

export default class Dashboard extends Component {
    constructor(props) {
        super(props);
        this.renderRow = this.renderRow.bind(this);
        this.state = {
            restaurants: [
                {
                    'name': 'برنامه ۳۰ روزه هوازی',
                    'address': 'چربی سوزی | کاهش وزن',
                    'image': { 'url': 'https://shoutem.github.io/static/getting-started/restaurant-1.jpg' },
                },
                {
                    'name': 'تمرین سینه',
                    'address': 'افزایش قدرت و حجم عضلات سینه و فرم دهی به آن',
                    'image': { 'url': 'https://shoutem.github.io/static/getting-started/restaurant-2.jpg' },
                },
                {
                    'name': 'تمرین شکم',
                    'address': 'حاضرید که عضلات شکمتان را ورزیده و تکه کنید؟ حرکاتی که در زیر آمده، راهنمایی است که همیشه برای شما کافی و مفید خواهد بود.',
                    'image': { 'url': 'https://shoutem.github.io/static/getting-started/restaurant-3.jpg' },
                },
                {
                    'name': 'تمرین سینه',
                    'address': 'افزایش قدرت و حجم عضلات سینه و فرم دهی به آن',
                    'image': { 'url': 'https://shoutem.github.io/static/getting-started/restaurant-2.jpg' },
                },
                {
                    'name': 'تمرین شکم',
                    'address': 'حاضرید که عضلات شکمتان را ورزیده و تکه کنید؟ حرکاتی که در زیر آمده، راهنمایی است که همیشه برای شما کافی و مفید خواهد بود.',
                    'image': { 'url': 'https://shoutem.github.io/static/getting-started/restaurant-3.jpg' },
                },
                {
                    'name': 'تمرین ران پا',
                    'address': 'این یک تست است.',
                    'image': { 'url': 'https://shoutem.github.io/static/getting-started/restaurant-2.jpg' },
                },
            ],
        };
    }

    renderRow(rowData, sectionId, index) {
    // rowData contains grouped data for one row,
    // so we need to remap it into cells and pass to GridRow
        if (index === '0') {
            return (
                <TouchableOpacity key={index}>
                    <ImageBackground
                        styleName="large"
                        source={{ uri: rowData[0].image.url }}
                    >
                        <Tile>
                            <Title styleName="md-gutter-bottom">{rowData[0].name}</Title>
                            <Subtitle styleName="sm-gutter-horizontal">{rowData[0].address}</Subtitle>
                        </Tile>
                    </ImageBackground>
                    <Divider styleName="line" />
                </TouchableOpacity>
            );
        }

        const cellViews = rowData.map((restaurant, id) => {
            return (
                <TouchableOpacity key={id} styleName="flexible">
                    <Card styleName="flexible">
                        <Image
                            styleName="medium-wide"
                            source={{ uri: restaurant.image.url  }}
                        />
                        <View styleName="content">
                            <Subtitle numberOfLines={3}>{restaurant.name}</Subtitle>
                            <View styleName="horizontal">
                                <Caption styleName="collapsible" numberOfLines={2}>{restaurant.address}</Caption>
                            </View>
                        </View>
                    </Card>
                </TouchableOpacity>
            );
        });

        return (
            <GridRow columns={2}>
                {cellViews}
            </GridRow>
        );
    }

    render() {
        const restaurants = this.state.restaurants;
        // Group the restaurants into rows with 2 columns, except for the
        // first restaurant. The first restaurant is treated as a featured restaurant
        let isFirstArticle = true;
        const groupedData = GridRow.groupByRows(restaurants, 2, () => {
            if (isFirstArticle) {
                isFirstArticle = false;
                return 2;
            }
            return 1;
        });

        return (
            <ListView
                data={groupedData}
                renderRow={this.renderRow}
            />
        );
    }
}

Profile.js

import React, { Component } from 'react';
import { Container, Header, Content, Form, Item, Input, Label } from 'native-base';

// import I18n from 'react-native-i18n';
// import {I18nManager} from 'react-native';
//          I18nManager.forceRTL(true);

export default class Profile extends Component {
    render() {
        return (
            <Container>
                <Header />
                <Content>
                    <Form>
                        <Item floatingLabel>
                            <Label>نام</Label>
                            <Input />
                        </Item>
                        <Item floatingLabel last>
                            <Label>قد (سانتیمتر)</Label>
                            <Input />
                        </Item>
                    </Form>
                </Content>
            </Container>
        );
    }
}

package.json

  "dependencies": {
    "@shoutem/ui": "^0.23.4",
    "native-base": "^2.4.2",
    "react": "16.3.1",
    "react-native": "0.55.3",
    "react-native-vector-icons": "^4.6.0",
    "react-navigation": "^1.0.3"
  },
  "devDependencies": {
    "babel-jest": "22.4.3",
    "babel-preset-react-native": "4.0.0",
    "eslint": "^4.19.1",
    "eslint-plugin-react": "^7.7.0",
    "jest": "22.4.3",
    "react-test-renderer": "16.3.1"
  },
  "jest": {
    "preset": "react-native"
  }

我已经尝试过最新版本的 react-navigation 所以它的降级版本你在 package.json

中看到

我 运行 它使用 react-native 运行-ios,所有选项卡都显示不同的屏幕。如果您指的是在主页选项卡上单击导航选项卡时导航选项卡不会更改的事实,则主页和导航选项卡都在使用仪表板屏幕。

以下是我的这个项目的 package.json 文件:

{
  "name": "a",
  "version": "0.0.1",
  "private": true,
  "scripts": {
    "start": "node node_modules/react-native/local-cli/cli.js start",
    "test": "jest"
  },
  "dependencies": {
    "react-native-code-push": "1.15.0-beta",
    "@babel/core": "^7.0.0-beta.40",
    "@shoutem/ui": "^0.23.4",
    "eslint": "^3.19.0",
    "native-base": "^2.4.2",
    "react": "16.3.1",
    "react-native": "0.55.3",
    "react-native-vector-icons": "^4.6.0",
    "react-navigation": "^1.5.11"
  },
  "devDependencies": {
    "babel-jest": "22.4.3",
    "babel-preset-react-native": "4.0.0",
    "jest": "22.4.3",
    "react-test-renderer": "16.3.1"
  },
  "jest": {
    "preset": "react-native"
  }
}

我已经找到了解决方案,我将尽可能具体地说明所有可能遇到此问题的人!

首先是I18nManager.forceRTL(true);的问题 当你在你的 react-native 代码的任何地方使用这行代码时,它的屏幕将被渲染,并且在第二次重新加载时,应用程序的布局正在更改为 RTL,即使你注释那行它也不会改变!您必须使用 I18nManager.forceRTL(false); 并重新加载几次才能恢复正常的 ltr 设置。

问题是......我们中的一些人真的需要像我想的那样改变 RTL 布局!猜猜是什么 react-navigation 不尊重这一点,至少现在和 TabNabigator 部门是这样。

总而言之:RN 上的 RTL 布局会破坏你的反应导航的标签导航! (从当前版本开始,您可以在上面的 packages.json 中看到)该问题仅使第一个可见,而对于其他选项卡则显示平淡无奇的选项卡,如果您打开动画或滑动其他选项卡将显示但选项卡行为正常以一种奇怪的方式,这意味着当第一个选项卡处于活动状态时最后一个选项卡处于活动状态,反之亦然......中间选项卡永远不会被关注。 所以您应该知道您不能将选项卡式导航与 RTL 布局一起使用。这个问题得到修复后我会更新这个答案!