【问题标题】:Need to show Expandable list view inside navigation drawer需要在导航抽屉内显示可扩展列表视图
【发布时间】:2017-12-12 06:30:28
【问题描述】:

我是一名 Android 应用程序开发人员。我已经开始研究 React-Native。我无法找到在导航抽屉内显示可扩展列表的方法。如果可以在其中完成此功能,请建议一个库。

navigationOptions 无法提供列表(请参阅下面的代码)。

我想显示类似项目 4 的可扩展视图

我的代码是:-

import {DrawerNavigator} from 'react-navigation';
import React, {Component} from 'react';
import {
  Platform,
  StyleSheet,
  Text,
  Image,
  View,
  TouchableHighlight
} from 'react-native';

import Screen1 from './screen/Screen1'
import Screen2 from './screen/Screen2'
const util = require('util');

class MyHomeScreen extends React.Component {

  constructor(props) {
    super(props);

    this.state = {
      headertitle: 'ffffff'
    };
  }

  componentWillReceiveProps(nextProps) {
    navigationOptions = {
      title: this.nextProps.headertitle
    };
  }

  static navigationOptions = {
    drawerLabel: 'Home',
    drawerIcon: ({tintColor}) => (
      <Image
      source={require('./images/document.png')}
      style={[
      styles.icon, {
        tintColor: tintColor
      }
    ]}/>),
    title: 'NIIT'
  };

  render() {

    return (<Screen1/>);
  }
}

class MyNotificationsScreen extends React.Component {
  static navigationOptions = {
    drawerLabel: 'Notifications',
    drawerIcon: ({tintColor}) => (<Image source={require('./images/smartphone.png')} style={[styles.icon]}/>),
    title: 'Gnome'
  };

  render() {
    return (<Screen2/>);
  }
}

const styles = StyleSheet.create({
  icon: {
    width: 24,
    height: 24
  }
});

const DrawerScreen = DrawerNavigator({
  Screen1: {
    screen: MyHomeScreen
  },
  Screen2: {
    screen: MyNotificationsScreen
  }
}, {headerMode: 'none'})

export default DrawerScreen;

【问题讨论】:

    标签: react-native navigation-drawer expandablelistview react-navigation


    【解决方案1】:

    我认为这是一个单一的类,是 OP 要求的简单实现。它使用反应导航 v5。它是通过ExpandableDrawerProps 配置的独立组件(title 是父抽屉的名称,即包含子抽屉且没有导航的内容,选择是标签名称到导航屏幕组件名称的映射。)它是用 TypeScript 编写(这两个都是 .tsx 文件),所以如果你不使用 TypeScript,只需去掉打字。

    import {
      DrawerContentComponentProps,
      DrawerContentScrollView,
      DrawerItem,
    } from '@react-navigation/drawer';
    import React from 'react';
    import { Text, View } from 'react-native';
    import { TouchableOpacity } from 'react-native-gesture-handler';
    import styles from './styles';
    
    export type ExpandableDrawerProps = DrawerContentComponentProps & {
      title: string;
      choices: Map<string, string>;
    };
    
    export default class ExpandableDrawer extends React.Component<
      ExpandableDrawerProps,
      {
        isExpanded: boolean;
      }
    > {
      constructor(props: ExpandableDrawerProps, state: { isExpanded: boolean }) {
        super(props);
        this.state = state;
      }
    
      onPress = (): void => {
        this.setState(() => {
          return {
            isExpanded: !this.state.isExpanded,
          };
        });
      };
    
      render = (): JSX.Element => {
        return (
          <View style={styles.container}>
            <TouchableOpacity
              activeOpacity={0.8}
              onPress={this.onPress}
              style={styles.heading}
            >
              <Text style={styles.expander}>{this.props.title}</Text>
            </TouchableOpacity>
    
            {this.state.isExpanded ? (
              <DrawerContentScrollView>
                <View style={styles.expandedItem}>
                  {[...this.props.choices.keys()].map(
                    (label: string): JSX.Element | null => {
                      const screen = this.props.choices.get(label);
                      if (screen != undefined) {
                        return (
                          <DrawerItem
                            key={label}
                            label={label}
                            onPress={(): void => {
                              this.props.navigation.navigate(screen);
                            }}
                          />
                        );
                      } else {
                        return null;
                      }
                    }
                  )}
                </View>
              </DrawerContentScrollView>
            ) : null}
          </View>
        );
      };
    }
    
    

    您可以将该代码放到一个文件中,创建一个简单的样式文件或从该代码中删除它们,然后您就可以在您的正常抽屉导航中使用<ExpandableDrawerMenu {...expandable} />

    这是我在普通导航抽屉中使用它的方式。

    const DrawerContent = (props: DrawerContentComponentProps): JSX.Element => {
      const c = new Map<string, string>();
      c.set('SubItem 1', 'SubItem1');
      c.set('SubItem 2', 'SubItem2');
      const expandable: ExpandableDrawerProps = {
        title: 'Expandable Drawer',
        choices: c,
        navigation: props.navigation,
        state: props.state,
        descriptors: props.descriptors,
        progress: props.progress,
      };
      return (
        <DrawerContentScrollView {...props}>
          <View style={styles.drawerContent}>
            <Drawer.Section style={styles.drawerSection}>
              <DrawerItem
                label="Item 1"
                onPress={(): void => {
                  props.navigation.navigate('Item1');
                }}
              />
    
              <ExpandableDrawerMenu {...expandable} />
    
              <DrawerItem>
                label="Item 2"
                onPress={(): void => {
                  props.navigation.navigate('Item2');
                }}
              />
              <DrawerItem
                label="Item 3"
                onPress={(): void => {
                  props.navigation.navigate('Item3');
                }}
              />
            </Drawer.Section>
          </View>
        </DrawerContentScrollView>
      );
    };
    
    export default class Navigator extends Component {
      render = (): JSX.Element => {
        const Drawer = createDrawerNavigator();
    
        return (
          <NavigationContainer>
            <Drawer.Navigator
              drawerContent={(props: DrawerContentComponentProps): JSX.Element =>
                DrawerContent(props)
              }
              initialRouteName="Item1"
            >
              <Drawer.Screen name="Item1" component={Item1Screen} />
              <Drawer.Screen name="SubItem1" component={SubItem1Screen} />
              <Drawer.Screen name="SubItem2" component={SubItem2Screen} />
              <Drawer.Screen name="Item2" component={Item2Screen} />
              <Drawer.Screen name="Item3" component={Item3Screen} />
            </Drawer.Navigator>
          </NavigationContainer>
        );
      };
    }
    

    【讨论】:

    • @Raja Simon -- 如果您仍在寻找简单的解决方案,我的回答可能会有所帮助。
    【解决方案2】:

    react-navigation 目前不支持抽屉式导航器中的可折叠菜单。

    但是,您可以通过向导航器提供自己的 contentComponent 来实现自己的:

    const DrawerScreen = DrawerNavigator({
      Screen1: {
        screen: MyHomeScreen
      },
      Screen2: {
        screen: MyNotificationsScreen
      }
    }, {
      headerMode: 'none',
      contentComponent: MyDrawer
    })
    
    const MyDrawer = (props) => ...
    

    更多信息请参见the documentation

    你可以使用react-native-collapsible之类的东西来实现折叠菜单本身的效果。

    【讨论】:

    • 如果可以在其中完成此功能,请建议一个库。
    • @HarishGyanani 你做过这个效果吗?给我一些指导如何进行?
    • @RajaSimon 立即查看我的答案
    【解决方案3】:

    我已经为这个问题开发了一个解决方案。我的代码使用
    "@react-navigation/drawer": "^5.1.1" 和
    "@react-navigation/native": "^5.0.9"。

    Gihub 链接 - https://github.com/gyanani-harish/ReactNative-ExpandableDrawerMenu

    【讨论】:

    • 请添加一些图片,图片会很有帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-20
    • 1970-01-01
    • 2015-04-11
    • 1970-01-01
    • 2014-05-04
    • 1970-01-01
    相关资源
    最近更新 更多