美文网首页RNAndroid知识React Native开发
react-native自定义PopupWindow实现

react-native自定义PopupWindow实现

作者: 王亟亟 | 来源:发表于2017-05-11 16:10 被阅读443次

    转载请注明出处:王亟亟的大牛之路

    自从泰国回来就忙的不行,各种开会,各种方案,各种报告。学习进度有些受阻,回家时间也比较晚整个人的状态也不是很高效,不如好好休息。
    今天下午强行挤了2小时把组里的一个小组件开源下,勉强算挤出一些产能吧。

    安利地址:
    Useful-Open-Source-Android 安卓收纳"裤"

    Useful-Open-Source-React-Native React-Native收纳"裤"

    虽然手头事情比较多,但是我还是尽量保持每日一更,每天都要有所收获!


    运行效果:

    实现思路:

    外观:
    三角形的"箭头"图形+一个视图组

    外观实现:
    因为设计的原因整个pop成为了2个个体,一个是三角,一个就是具体内容窗体。
    三角可以使用切图,但是自己用ART.Path()实现拓展性更好,毕竟不用因为超大屏手机去做代码修改。
    下面一部分就是一个正常的<View>多个<TouchableOpacity/></View>
    (这里没用listview来实现列表,各位看官也可以自行修改,修改成本不是很高,毕竟js可以传方法,所以点击行为也可以传props解决)

    事件:
    展现/消失由外层容器控制,控件内对应字段为isVisible: this.props.show


    使用与分析:

    源码地址:react-native-popupWindow

    团队开源内容地址(我们会继续努力):https://github.com/PacteraOpenSourceGroup

    控件产出:wwl901215

    ok,流程走完 我们读一下这个弹窗控件的源码(标注是我发文前加的,给新手学习理解用,如果影响高端玩家读源码抱歉)

    如何使用(第一版,暂不考虑发布npm)

    import MenuPopWindow from '你存放的位置'
    

    实际使用

    <MenuPopWindow width={60} height={100} show={this.state.showPop} closeModal={(show) => { this.setState({ showPop: show }) }} dataArray={['第一!!', '第二!!', '第三!!']} />
    
    import React from 'react'
    import {
        StyleSheet,
        View,
        Text,
        Image,
        TouchableOpacity,
        Alert,//弹窗
        Modal,
        Dimensions,//用于获取设备屏幕的宽高
        ART,//绘图,Android默认就包含ART库,IOS需要单独添加依赖库
    } from 'react-native'
    const { width, height } = Dimensions.get('window');
    let mwidth = 70;
    let mheight = 100;
    const bgColor = '#2d2d2d';//背景色,没有设置外部传入
    const top = 50;
    let dataArray;//列表数据源
    export default class MenuModal extends React.Component {
    
        constructor(props) {
            super(props);
            this.state = {
                isVisible: this.props.show,
            }
            //数据传递
            mwidth = this.props.width || 70;
            mheight = this.props.height || 100;
            dataArray = this.props.dataArray;
        }
    
        componentWillReceiveProps(nextProps) {
            this.setState({ isVisible: nextProps.show });
        }
        //处理状态
        closeModal() {
            this.setState({
                isVisible: false
            });
            this.props.closeModal(false);
        }
    
        render() {
            //绘制路径
            const path = ART.Path();
            path.moveTo(width - 10 - mwidth * 1 / 3 + 3, top);
            path.lineTo(width - 10 - mwidth * 1 / 3 + 9, top - 7);
            path.lineTo(width - 10 - mwidth * 1 / 3 + 15, top);
            path.close();
            return (
                <View style={styles.container}>
                    <Modal
                        transparent={true}
                        visible={this.state.isVisible}
                        //动画效果类型
                        animationType={'fade'}
                        onRequestClose={() => this.closeModal()}>
                        <TouchableOpacity style={styles.container} activeOpacity={1} onPress={() => this.closeModal()}>
                            <ART.Surface width={width} height={100} >
                                <ART.Shape d={path} fill={bgColor} />
                            </ART.Surface>
                            <View style={styles.modal}>
                                <TouchableOpacity activeOpacity={1} onPress={() => Alert.alert('点击了第1个')} style={styles.itemView}>
                                    <Image style={styles.imgStyle} source={require('../res/icon_qr.png')} />
                                    <Text style={styles.textStyle}>{dataArray[0]}</Text>
                                </TouchableOpacity>
                                <TouchableOpacity activeOpacity={1} onPress={() => Alert.alert('点击了第2个')} style={[styles.itemView, { borderColor: '#999', borderTopWidth: 1, borderBottomWidth: 1 }]}>
                                    <Image style={styles.imgStyle} source={require('../res/icon_qr.png')} />
                                    <Text style={styles.textStyle}>{dataArray[1]}</Text>
                                </TouchableOpacity>
                                <TouchableOpacity activeOpacity={1} onPress={() => Alert.alert('点击了第3个')} style={styles.itemView}>
                                    <Image style={styles.imgStyle} source={require('../res/icon_qr.png')} />
                                    <Text style={styles.textStyle}>{dataArray[2]}</Text>
                                </TouchableOpacity>
                            </View>
                        </TouchableOpacity>
                    </Modal>
                </View>
            )
        }
    }
    //样式链
    const styles = StyleSheet.create({
        container: {
            width: width,
            height: height,
        },
        modal: {
            backgroundColor: bgColor,
            // opacity:0.8,
            width: mwidth,
            height: mheight,
            position: 'absolute',
            left: width - mwidth - 10,
            top: top,
            padding: 5,
            justifyContent: 'center',
            alignItems: 'center',
            borderRadius: 3,
        },
        itemView: {
            flexDirection: 'row',
            justifyContent: 'center',
            alignItems: 'center',
            flex: 1,
        },
        textStyle: {
            color: '#fff',
            fontSize: 14,
            marginLeft: 2,
        },
        imgStyle: {
            width: 12,
            height: 12,
        }
    });
    

    感谢各位观众老爷!

    相关文章

      网友评论

        本文标题:react-native自定义PopupWindow实现

        本文链接:https://www.haomeiwen.com/subject/aqgotxtx.html