Расположение вкладок (нижняя вкладка реагирования навигации) разбито на iPhone с отображением метки - PullRequest
0 голосов
/ 22 апреля 2020

Дизайн макета вкладки нарушен в iPhone X. Я использую реагировать-навигация / нижние вкладки: ^ 5.0.6 . Я использовал SafeAreaProvider в качестве оболочки. Вот мой код ниже.

HomeScreen. js

const Stack = createStackNavigator();
const Tab = createBottomTabNavigator();

function notificationStack() {
  return (
    <Stack.Navigator>
      <Stack.Screen
        name="Notification"
        component={NotificationScreen}
        options={{
          title: Constants.strings.notification,
          headerLeft: () => (
            <Image
              style={style.headerIcon}
              source={require('./image/top_bar/top_bar_notification_icon.png')}
            />
          ),
          headerStyle: {
            backgroundColor: Constants.color.bgColor,
          },
          headerTintColor: Constants.color.primaryColor,
          headerTitleStyle: {
            fontSize: Constants.dimensions.fontSize16,
            fontFamily: Constants.fonts.fontFamilyBold,
          },
        }}
      />
    </Stack.Navigator>
  );
}

function feedStack({navigation}) {
  return (
    <Stack.Navigator initialRouteName="Feed">
      <Stack.Screen
        name="Feed"
        component={FeedScreen}
        options={{
          title: Constants.strings.feed,
          headerLeft: () => (
            <Image
              style={style.headerIcon}
              source={require('./image/top_bar/top_bar_feed_icon.png')}
            />
          ),
          headerRight: () => (
            <TouchableOpacity
              onPress={() => navigation.navigate('Search')}
              style={{marginRight: 16}}>
              <Image
                style={style.overflowIcon}
                source={require('./image/top_bar/top_bar_search_icon.png')}
              />
            </TouchableOpacity>
          ),
          headerStyle: {
            backgroundColor: Constants.color.bgColor,
          },
          headerTintColor: Constants.color.primaryColor,
          headerTitleStyle: {
            fontSize: Constants.dimensions.fontSize16,
            fontFamily: Constants.fonts.fontFamilyBold,
          },
        }}
      />
      <Stack.Screen
        name="Search"
        component={SearchScreen}
        options={{headerShown: false}}
      />
    </Stack.Navigator>
  );
}

function profileStack({navigation}) {
  return (
    <Stack.Navigator>
      <Stack.Screen
        name="Profile"
        component={ProfileScreen}
        options={{
          title: Constants.strings.profile,
          headerLeft: () => (
            <Image
              style={style.headerIcon}
              source={require('./image/top_bar/top_bar_profile_icon.png')}
            />
          ),
          headerRight: () => (
            <ProfileOverflowMenu
              onChangePasswordClicked={() => {
                navigation.navigate('ChangePassword');
              }}
              onLogOutClicked={() => {}}
            />
          ),
          headerStyle: {
            backgroundColor: Constants.color.bgColor,
          },
          headerTintColor: Constants.color.primaryColor,
          headerTitleStyle: {
            fontSize: Constants.dimensions.fontSize16,
            fontFamily: Constants.fonts.fontFamilyBold,
          },
        }}
      />
    </Stack.Navigator>
  );
}

function homeTabNavigator() {
  return (
    <Tab.Navigator
      initialRouteName="Feed"
      tabBarOptions={{
        style: {
          backgroundColor: Constants.color.tabBarBgColor,
          height: Constants.dimensions.tabBarHeight,
        },
        activeTintColor: Constants.color.activeTintColor,
        inactiveTintColor: Constants.color.inactiveTintColor,
        labelStyle: {
          fontSize: Constants.dimensions.fontSize12,
          fontFamily: Constants.fonts.fontFamilyLight,
          marginBottom: Constants.dimensions.marginPadding8,
        },
      }}>
      <Tab.Screen
        name="Notification"
        component={notificationStack}
        options={{
          tabBarLabel: Constants.strings.notification,
          tabBarIcon: ({tintColor, focused}) => (
            <Image
              style={style.tabBarIcon}
              source={
                focused
                  ? require('./image/tab_bar/tab_notification_active.png')
                  : require('./image/tab_bar/tab_notification_inactive.png')
              }
            />
          ),
        }}
      />
      <Tab.Screen
        name="Feed"
        component={feedStack}
        options={{
          tabBarLabel: Constants.strings.feed,
          tabBarIcon: ({tintColor, focused}) => (
            <Image
              style={style.tabBarIcon}
              source={
                focused
                  ? require('./image/tab_bar/tab_feed_active.png')
                  : require('./image/tab_bar/tab_feed_inactive.png')
              }
            />
          ),
        }}
      />
      <Tab.Screen
        name="Profile"
        component={profileStack}
        options={{
          tabBarLabel: Constants.strings.profile,
          tabBarIcon: ({tintColor, focused}) => (
            <Image
              style={style.tabBarIcon}
              source={
                focused
                  ? require('./image/tab_bar/tab_profile_active.png')
                  : require('./image/tab_bar/tab_profile_inactive.png')
              }
            />
          ),
        }}
      />
    </Tab.Navigator>
  );
}

class HomeScreen extends React.Component {
  profileMenu = null;

  setMenuRef = ref => {
    this.profileMenu = ref;
  };

  hideMenu = () => {
    this.profileMenu.hide();
  };

  showMenu = () => {
    this.profileMenu.show();
  };

  render() {
    return (
      <SafeAreaProvider>
        <NavigationContainer>
          <Stack.Navigator initialRouteName="Home">
            <Stack.Screen
              name="Home"
              component={homeTabNavigator}
              options={{headerShown: false}}
            />
            <Stack.Screen
              name="ChangePassword"
              component={ChangePasswordScreen}
              options={{
                headerShown: true,
                title: Constants.strings.change_password,
                headerStyle: {
                  backgroundColor: Constants.color.bgColor,
                },
                headerTintColor: Constants.color.primaryColor,
                headerTitleStyle: {
                  fontSize: Constants.dimensions.fontSize16,
                  fontFamily: Constants.fonts.fontFamilyBold,
                },
              }}
            />
          </Stack.Navigator>
        </NavigationContainer>
      </SafeAreaProvider>
    );
  }
}

export default HomeScreen;

FeedScreen. js

const listData = [
  {
    key: '1',
    title: 'Title One',
    date: '24th Feb 2020',
    body:
      "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.",
    topic: 'Topic one',
  },
  {
    key: '2',
    title: 'Title Two',
    date: '22nd Feb 2020',
    body:
      'Lorem Ipsum is simply dummy text of the printing and typesetting industry.',
    topic: 'Topic test',
  },
  {
    key: '3',
    title:
      'Title Three to test the long title if it is rendering properly or not',
    date: '19th Feb 2020',
    body:
      "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.",
    topic: 'Topic sports',
  },
  {
    key: '4',
    title: 'Title Four',
    date: '17th Feb 2020',
    body: 'This is a body.',
    topic: 'Topic one',
  },
  {
    key: '5',
    title: 'This is a title',
    date: '15th Feb 2020',
    body:
      "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.",
    topic: 'Topic one',
  },
  {
    key: '6',
    title: 'Title',
    date: '15th Feb 2020',
    body:
      "There are many variations of passages of Lorem Ipsum available, but the majority have suffered alteration in some form, by injected humour, or randomised words which don't look even slightly believable. If you are going to use a passage of Lorem Ipsum, you need to be sure there isn't anything embarrassing hidden in the middle of text. All the Lorem Ipsum generators on the Internet tend to repeat predefined chunks as necessary, making this the first true generator on the Internet. It uses a dictionary of over 200 Latin words, combined with a handful of model sentence structures, to generate Lorem Ipsum which looks reasonable. The generated Lorem Ipsum is therefore always free from repetition, injected humour, or non-characteristic words etc.",
    topic: 'Topic information',
  },
];

class FeedScreen extends React.Component {
  // only renders each list item
  renderRow({item}) {
    const title = `${item.title}`;
    const date = `${item.date}`;
    const body = `${item.body}`;
    const topic = `${item.topic}`;

    let actualRowComponent = (
      <View style={styles.feedRow}>
        <View style={styles.feedItemTitleDateHolder}>
          <Text
            style={styles.feedItemTitleStyle}
            numberOfLines={1}
            ellipsizeMode={'tail'}>
            {title}
          </Text>
          <Text style={styles.feedItemDateStyle}>{date}</Text>
        </View>
        <Text
          style={styles.feedItemBodyStyle}
          numberOfLines={5}
          ellipsizeMode={'tail'}>
          {body}
        </Text>
        <View style={styles.feedItemTopicHolder}>
          <Text style={styles.feedItemTopicLabelStyle}>
            {Constants.strings.topic}
          </Text>
          <Text style={styles.feedItemTopicLabelStyle}>
            {Constants.strings.colon}
          </Text>
          <Text style={styles.feedItemTopicValueStyle}>{topic}</Text>
        </View>
      </View>
    );

    let touchableWrapperIos = (
      <TouchableHighlight
        activeOpacity={0.5}
        underlayColor={'#FFFFFF00'}
        onPress={() => {
          //this._navigation.navigate('DetailsRoute', {...item});
        }}>
        {actualRowComponent}
      </TouchableHighlight>
    );

    let touchableWrapperAndroid = (
      <TouchableNativeFeedback
        useForeground={true}
        background={TouchableNativeFeedback.SelectableBackgroundBorderless()}
        onPress={() => {
          //this._navigation.navigate('DetailsRoute', {...item});
        }}>
        {actualRowComponent}
      </TouchableNativeFeedback>
    );

    if (require('react-native').Platform.OS === 'ios') {
      return touchableWrapperIos;
    } else {
      return touchableWrapperAndroid;
    }
  }

  render() {
    return (
      <>
        <StatusBar
          barStyle="light-content"
          hidden={false}
          backgroundColor={Constants.color.statusBarColor}
          translucent={false}
        />
        <SafeAreaView style={styles.feedBg}>
          <FlatList
            style={styles.feedContainer}
            data={listData}
            keyExtractor={(item, index) => item.key}
            renderItem={this.renderRow}
          />
        </SafeAreaView>
      </>
    );
  }
}

export default FeedScreen;

Вот скриншот, ниже которого я получаю iOS

enter image description here

Вот скриншот, ниже которого я получаю android

enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...