在下一次按下时关闭React-Native的下拉列表

时间:2017-09-26 19:06:39

标签: javascript react-native

我有一个ScrollView,其中包含多个View个组件作为子项。每个孩子都可以下拉。

打开按钮上的下拉按钮可以正常工作。

关闭同一按钮上的下拉列表或按下下拉列表中的某些内容时也是如此。

现在我给了这个用户,他们只是在下拉菜单上打开下拉菜单而没有选择任何内容或者打扰关闭打开的下拉列表。

如果用户想要做一些不同的事情,有没有办法在下拉列表打开后为屏幕上的下一次按下设置事件处理程序,以便关闭下拉列表

修改

这是我的实施方式:

const App = () =>
  <View>
    ...
    <List items={["one", "two", "three"]}/>
    ...
  </View>

const List = props =>
  <ScrollView>
    {props.items.map(i => <ListItem name={i} key={i}/>)}
  </ScrollView>


class ListItem extends React.Component {
  state = { showDropdown: false};

  handleDropdown = () =>
    this.setState(state =>
      ({showDropdown: !state.showDropdown})
    );

  render() {
    return <View>
      <TouchableOpacity onPress={this.handleDropdown}>
        <Text>{this.props.name}</Text>
      </TouchableOpacity>
      {this.state.showDropdown &&
        <Dropdown>
          <DropdownItem onPress={this.handleDropdown}/>
        </Dropdown>
      }
    </View> 
  }
}

当我再次点击ListItem或点击DropdownItem时,该下拉列表就会关闭。

但是当我点击屏幕上的其他地方时,我也希望它关闭List组件及其子组件。

3 个答案:

答案 0 :(得分:1)

找到解决方案。

我向我的应用根PanResponder添加了View并使用了此配置:

const handlers = []
const addHandler = handler => handlers.push(handler);
const handleNextPress = (event, state) => handlers.forEach(h => h(event, state));

this.panResponder = PanResponder.create({
  onStartShouldSetPanResponder: () => true,
  onStartShouldSetPanResponderCapture: (event, state) =>
    handleNextPress(event, state)
});

// somewhere else in the app
addHandler(this.closeMyDropdown);

每次触摸时都会调用onStartShouldSetPanResponderCapture方法来检查是否应捕获触摸事件。如果它返回一个假值,则不会捕获该事件并触及可触摸的组件。

此方法允许潜入处理程序,这些处理程序可以在事件触及应用程序的可触摸组件之前执行操作,或者在可触摸组件对事件做出反应后使用超时来发生事情。

答案 1 :(得分:0)

你可以做的是在下拉菜单上设置一个参考号 ref="dropdown" 并按下按钮

onPress={() => this.refs.dropdown.blur(); }

这就像定义一个id并点击按钮点击以告诉它将会模糊

答案 2 :(得分:0)

理想情况下,您需要将下拉列表设为受控组件,其中包含控制下拉列表是否显示的道具,以及组件在点击时调用的回调。

然后,您可以将活动下拉列表ID保留在父组件状态中,当更改后,所有下拉列表都应该重新呈现

类似的东西:

class List extends Component {
    state = {
        openDrowdownId: null
    }

    openDropDown = id => {
        this.setState({ openDropDownId: id });
    }

    closeDropDown = () => {
        this.setState({ openDropDownId: null });
    }

    render() {
        return (
            <ScrollView>
                {this.props.items.map(item => (
                    <View key={item.id}>
                        <Dropdown 
                            isOpen={this.state.openDropDownId === item.id} 
                            open={() => this.openDropDown(item.id)}
                        />
                    </View>
                ))}
            </ScrollView>
        )
    }
}