首页 > 解决方案 > 在 React Native 中单击 3 个点时打开菜单的更好解决方案

问题描述

当为每个项目单击 3 个点图标时,我可以打开菜单。但是代码可以以更好的方式编写..

现在正在为每个卡片项目创建菜单,但理想情况下,最好创建单个菜单视图并将其动态关联到单击3 个点的某个卡片。

世博源代码链接

代码

export default class App extends React.Component {

  constructor(props, ctx) {
    super(props, ctx);
    this.state = {
      list: [
        { name: "Michael", mobile: "9292929292", ref: React.createRef() },
        { name: "Mason Laon Roah", mobile: "1232313233", ref: React.createRef() },
        { name: "Constructor", mobile: "4949494949", ref: React.createRef() },
        { name: "Rosling", mobile: "4874124584", ref: React.createRef() }
      ],
    };
  }

  _menu = null;

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

  showMenu = (ref) => {
    this._menu = ref;
    this._menu.show();
  };

  render() {
    const renderItem = ({ item, index }) => (
      <ListItem
          title={
            <View>
              <Text style={{ fontWeight: "bold" }}>{item.name}</Text>
              <Text>{item.mobile}</Text>
            </View>
          }
          subtitle={
            <View>
              <Text>445 Mount Eden Road, Mount Eden, Auckland. </Text>
              <Text>Contact No: 134695584</Text>
            </View>
          }
          leftAvatar={{ title: 'MD' }}
          rightContentContainerStyle={{ alignSelf: 'flex-start'}}
          rightTitle={this.getMenuView(item.ref)}
        />
    );

    return (
      <View style={styles.container}>
        <View style={{ flex: 1, marginTop: 30 }}>
          <FlatList
            showsVerticalScrollIndicator={false}
            keyExtractor={(item, index) => index.toString()}
            data={this.state.list || null}
            renderItem={renderItem}
            ItemSeparatorComponent={() => (
              <View style={{ marginBottom: 5 }} />
            )}
          />
        </View>
      </View>     
    );
  }

  getMenuView(ref) {
    return (
      <Menu
          ref={ref}
          button={<Icon onPress={() => this.showMenu(ref.current)} type="material" color="red" name="more-vert" />}
        >
          <MenuItem onPress={this.hideMenu}>Menu item 1</MenuItem>
          <MenuItem onPress={this.hideMenu}>Menu item 2</MenuItem>
          <MenuItem onPress={this.hideMenu} disabled>
            Menu item 3
          </MenuItem>
          <MenuDivider />
          <MenuItem onPress={this.hideMenu}>Menu item 4</MenuItem>
      </Menu>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    backgroundColor: '#ecf0f1',
    padding: 8,
  },
});

样本输出

标签: react-native

解决方案


如此处所述,您可以找到一个未记录的UIManager.java类,该类允许您使用其showPopupMenu方法创建 Popups。

这目前仅适用于 Android。

import React, { Component } from 'react'
import { View, UIManager, findNodeHandle, TouchableOpacity } from 'react-native'
import Icon from 'react-native-vector-icons/MaterialIcons'

const ICON_SIZE = 24

export default class PopupMenu extends Component {
  constructor (props) {
    super(props)
    this.state = {
      icon: null
    }
  }

  onError () {
    console.log('Popup Error')
  }

  onPress = () => {
    if (this.state.icon) {
      UIManager.showPopupMenu(
        findNodeHandle(this.state.icon),
        this.props.actions,
        this.onError,
        this.props.onPress
      )
    }
  }

  render () {
    return (
      <View>
        <TouchableOpacity onPress={this.onPress}>
          <Icon
            name='more-vert'
            size={ICON_SIZE}
            color={'grey'}
            ref={this.onRef} />
        </TouchableOpacity>
      </View>
    )
  }

  onRef = icon => {
    if (!this.state.icon) {
      this.setState({icon})
    }
  }
}

然后如下使用它。

render () {
    return (
      <View>
        <PopupMenu actions={['Edit', 'Remove']} onPress={this.onPopupEvent} />
      </View>
    )
  }

onPopupEvent = (eventName, index) => {
    if (eventName !== 'itemSelected') return
    if (index === 0) this.onEdit()
    else this.onRemove()
}

来源:https ://cmichel.io/how-to-create-a-more-popup-menu-in-react-native


推荐阅读