


使用方式:
<NurMenuModal
onItemClick={(item, index) => {
console.log(`item: ${item}\nindex:${index}`);
}}
data={[{text:'tableName'}]}
requestClose={() => this.setState({visible: false})}
visible={visible}/>
说明:
- data =>
[{text:'name',icon:{uri:'https://jianshu.com/s.png'}},{text:'name',icon:require('..')}},]
如果你想使用有一个icon并有个文字的menu的话那你写一个array然后它里面再写一个object{text:'',icon:''}
就可以了(这里的text是table的文字icon是图标。。。)
列子:
import React, {Component} from 'react'
import {View} from 'react-native'
import NurMenuModal from "./NurMenuModal";
export default class NurApp extends Component {
constructor(props) {
super(props);
this.state = {}
}
render() {
const {visible} = this.state;
let data = [
{
text: 'table 1',
},
{
text: 'table 2',
},
{
text: 'table 3',
}];
return (
<View style={[{flex:1}]}>
...
<NurMenuModal
onItemClick={(item, index) => {
console.log(`item: ${item}\nindex:${index}`);
}}
data={data}
requestClose={() => this.setState({visible: false})}
visible={visible}/>
</View>
)
}
}
组件 (NurMenuModal.js)
import React, {Component} from 'react'
import {
Image,
LayoutAnimation,
Platform,
ScrollView,
StyleSheet,
Text,
TouchableOpacity,
UIManager,
View,
} from 'react-native'
export default class NurMenuModal extends Component {
constructor(props) {
super(props);
this.state = {
boxVisible: true,
itemAnim: false,
}
}
propTypes: {
visible: PropTypes.boolean,
/**
* data={[]}
*/
data: PropTypes.array,
/**
* requestClose={()=>{
* ...
* }}
*/
requestClose: PropTypes.func,
/**
* 点击方法
* onItemClick={(item,index)=>{
* ...
* }}
*/
onItemClick: PropTypes.func,
};
startAnim(start) {
if (Platform.OS === 'android') {
UIManager.setLayoutAnimationEnabledExperimental(true);
}
LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut);
setTimeout(() => {
this.setState({
boxVisible: start,
itemAnim: start,
})
}, start ? 100 : 300)
}
renderItem(item, index) {
const {visible, onItemClick, requestClose} = this.props;
const {itemAnim} = this.state;
return <TouchableOpacity
style={[styles.item, {bottom: itemAnim ? 0 : 20}]}
onPress={() => {
onItemClick && onItemClick(item, index);
requestClose && requestClose();
}}>
<Text
numberOfLines={1}
style={{color: 'black', maxWidth: '85%'}}>{visible && item.text}</Text>
{visible && <Image style={styles.icon} source={item.icon}/>}
</TouchableOpacity>;
}
render() {
const {visible, data, requestClose} = this.props;
if (!data) return null;
if (data.length < 0) return null;
let {boxVisible} = this.state;
if (visible)
boxVisible = visible;
if (visible !== this.visible) {
this.visible = visible;
this.startAnim(visible);
}
return (
<TouchableOpacity
activeOpacity={1}
onPress={() => requestClose && requestClose()}
style={boxVisible && {
flex: 1,
position: 'absolute',
left: 0,
right: 0,
top: 0,
bottom: 0,
elevation: 10,
}}>
<View style={[styles.box, {height: (data.length + 1) * 50}, !visible && {minWidth: 0, height: 0,}]}>
<ScrollView>
{data.map((item, index) => this.renderItem(item, index))}
</ScrollView>
</View>
</TouchableOpacity>
)
}
}
const styles = StyleSheet.create({
box: {
position: 'absolute',
backgroundColor: 'white',
elevation: 10,
minWidth: 160,
maxHeight: '80%',
right: 10,
top: 10,
},
item: {
justifyContent: 'space-between',
flexDirection: 'row',
alignItems: 'center',
height: 40,
paddingHorizontal: 16,
},
icon: {
width: 22,
height: 22,
tintColor: 'black',
}
});
这是我由于工资想要而写的。。。所以可能有一些小问题。如果有改的地方的话直接留言。thanks
网友评论