[英]Closing a dropdown in React-Native on the next press
我有一個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
組件及其子項之外的屏幕其他位置時,我也希望它關閉。
找到了解決方案。
我在我的應用程序根View
添加了PanResponder
並使用了以下配置:
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
方法。 如果返回假值,則不會捕獲事件並擊中可觸摸的組件。
此方法允許潛入可以在事件擊中應用的可觸摸組件之前執行操作的處理程序,或使用超時讓事情在可觸摸組件對事件做出反應之后發生。
您可以做的是在下拉菜單中設置ref,例如ref="dropdown"
並在按鈕上按
onPress={() => this.refs.dropdown.blur(); }
這就像定義一個id並在按鈕上單擊以表明這將變得模糊
理想情況下,您需要使下拉列表成為受控組件,並帶有控制該下拉列表是否顯示的道具,以及在點擊該組件時調用的回調。
然后,您可以將活動下拉列表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>
)
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.