zoukankan      html  css  js  c++  java
  • ReactNative封装的优雅居中/底部弹出框

    /*
     * @Date: 2019-08-30 16:05:37
     * @Description: 真的不想每次都写个Modal了。
     * @Author: zhangji
     * @LastEditors: ZhangJi
     * @LastEditTime: 2019-09-02 11:16:51
     */
    
    import React from "react";
    import _ from "lodash";
    import {
      View,
      StyleSheet,
      Component,
      Platform,
      ActivityIndicator,
      FlatList,
      Image,
      TouchableWithoutFeedback,
      TouchableOpacity,
      Text,
      Alert,
      Modal,
      RefreshControl,
      NativeModules,
      ScrollView,
      TekLoadingDialog,
      LayoutAnimation
    } = 'react-native';
    
    
    /**
     * 通用弹出框,包括居中弹出框和底部弹出框
     * @param {Boolean} isVisible 控制是否可见
     * @param {?Boolean} isBottomView 可选,控制是否为底部弹出框样式,默认为居中弹出框
     * @param {?Boolean} isTouchMaskToClose 可选,控制是否点击阴影关闭弹窗,默认开启
     * @param {?String} title 可选,标题,默认为`提示`,只对居中弹窗生效
     * @param {?String} confirmText 可选,居中框的确认按钮描述,默认为`确 认`
     * @param {?JSX} customTitleView 可选,自定义title样式(包括居中和底部弹框),若该属性有值,会覆盖默认样式,当需要自定义按钮点击功能时可以用这个,
     * @param {?JSX} customBottomView 可选,自定义底部样式(包括居中和底部弹框),若该属性有值,会覆盖默认样式,当需要自定义按钮点击功能时可以用这个,
     *
     * eg:` <MyModal
     *         isVisible={this.state.isVisible}
     *      >
     *          <Text>测试弹窗</Text>
     *      </MyModal>`
     */
    export default class MyModal extends Component {
      constructor(props) {
        super(props);
        this.title = props.title || "提示";
        this.confirmText = props.confirmText || "确 认";
        this.customTitleView = props.customTitleView
          ? props.customTitleView
          : false;
        this.customBottomView = props.customBottomView
          ? props.customBottomView
          : false;
        this.isBottomView = !!JSON.stringify(props.isBottomView)
          ? this.props.isBottomView
          : false;
        this.isTouchMaskToClose = !!JSON.stringify(props.isTouchMaskToClose)
          ? this.props.isTouchMaskToClose
          : true;
    
        this.state = {
          isVisible: this.props.isVisible || false
        };
      }
    
      setModalVisiable(state) {
        this.setState({
          isVisible: state
        });
      }
    
      componentWillReceiveProps(newProps) {
        if (!_.isEmpty(this.props, newProps)) {
          if (this.state.isVisible != newProps.isVisible) {
            this.setState({
              isVisible: newProps.isVisible
            });
          }
        }
      }
    
      render() {
        return (
          <Modal
            animationType="fade"
            transparent={true}
            visible={this.state.isVisible}
            onRequestClose={() => {
              this.setModalVisiable(false);
            }}
          >
            {this.isBottomView ? (
              <View style={styles.bottomModalContainer}>
                <TouchableOpacity
                  style={styles.bottomMask}
                  onPress={() => {
                    this.setModalVisiable(false);
                  }}
                />
                <View style={styles.bottomContent}>{this.props.children}</View>
                {this.customBottomView ? (
                  this.customBottomView
                ) : (
                  <View style={styles.bottomBtns}>
                    <TouchableOpacity
                      onPress={() => {
                        this.setModalVisiable(false);
                      }}
                    >
                      <View
                        style={[
                          styles.bottomBtnsView,
                          { borderWidth: 0.5, borderColor: "#999" }
                        ]}
                      >
                        <Text
                          style={[
                            styles.bottomBtnsText,
                            { color: "#333", fontFamily: "PingFangSC-Light" }
                          ]}
                        >
                          取消
                        </Text>
                      </View>
                    </TouchableOpacity>
                    <TouchableOpacity onPress={() => {}}>
                      <View
                        style={[
                          styles.bottomBtnsView,
                          {
                            backgroundColor: "#417EFF",
                            borderWidth: 0.5,
                            borderColor: "#417EFF"
                          }
                        ]}
                      >
                        <Text
                          style={[
                            styles.bottomBtnsText,
                            { color: "#fff", fontWeight: "bold" }
                          ]}
                        >
                          确定
                        </Text>
                      </View>
                    </TouchableOpacity>
                  </View>
                )}
              </View>
            ) : (
              <View style={styles.modalContainer}>
                <TouchableWithoutFeedback
                  onPress={() => {
                    this.isTouchMaskToClose ? this.setModalVisiable(false) : null;
                  }}
                >
                  <View style={styles.mask} />
                </TouchableWithoutFeedback>
                <View style={styles.container}>
                  {this.customTitleView ? (
                    this.customTitleView
                  ) : (
                    <Text style={styles.title}>{this.title}</Text>
                  )}
                  {this.props.children}
                  <View
                    style={{
                      height: 0.5,
                      width: appConfig.ScreenWidth - 42,
                      backgroundColor: "#E5E5E5"
                    }}
                  />
                  {this.customBottomView ? (
                    this.customBottomView
                  ) : (
                    <TouchableOpacity onPress={() => this.setModalVisiable(false)}>
                      <Text style={styles.confirmBtn}>{this.confirmText}</Text>
                    </TouchableOpacity>
                  )}
                </View>
              </View>
            )}
          </Modal>
        );
      }
    }
    
    const styles = StyleSheet.create({
      modalContainer: {
        flex: 1,
        justifyContent: "center",
        alignItems: "center",
        width: appConfig.ScreenWidth,
        height: appConfig.ScreenHeight
      },
      mask: {
        width: appConfig.ScreenWidth,
        height: appConfig.ScreenHeight,
        backgroundColor: "rgba(0,0,0,.4)",
        position: "absolute",
        left: 0,
        top: 0
      },
      container: {
        width: appConfig.ScreenWidth - 30,
        backgroundColor: "#FFF",
        borderTopLeftRadius: 9,
        borderTopRightRadius: 9,
        borderBottomLeftRadius: 9,
        borderBottomRightRadius: 9,
        justifyContent: "center",
        alignItems: "center"
      },
      title: {
        textAlign: "center",
        fontFamily: "PingFangSC-Semibold",
        fontSize: 16,
        color: "#333",
        marginTop: 18
      },
      confirmBtn: {
        color: "#417EFF",
        fontSize: 17,
        fontFamily: "PingFangSC-Semibold",
        marginBottom: 18,
        marginTop: 14.2,
        width: appConfig.ScreenWidth - 42,
        textAlign: "center"
      },
    
      bottomModalContainer: {
        flex: 1,
        justifyContent: "flex-end",
        width: appConfig.ScreenWidth,
        height: appConfig.ScreenHeight
      },
      bottomMask: {
        flex: 1,
        width: appConfig.ScreenWidth,
        marginBottom: -9,
        backgroundColor: "rgba(0,0,0,.4)"
      },
      content: {
        width: appConfig.ScreenWidth,
        backgroundColor: "#FFF",
        borderTopLeftRadius: 9,
        borderTopRightRadius: 9,
        paddingTop: 15
      },
      bottomBtns: {
        flexDirection: "row",
        alignItems: "center",
        justifyContent: "space-around",
        backgroundColor: "#fff",
        marginBottom: appConfig.StatusBarHeight == 44 ? 34 : 0,
        shadowColor: "#00000033",
        shadowOffset: { width: 0, height: -9 },
        shadowOpacity: 0.1,
        shadowRadius: 6,
        elevation: 10
      },
      bottomBtnsView: {
        width: 165,
        height: 42,
        borderRadius: 100,
        marginTop: 12,
        marginBottom: 12,
        justifyContent: "center",
        alignItems: "center"
      },
      bottomBtnsText: {
        fontSize: 16
      },
      bottomModalContainer: {
        flex: 1,
        justifyContent: "flex-end",
        width: appConfig.ScreenWidth,
        height: appConfig.ScreenHeight
      },
      bottomMask: {
        flex: 1,
        width: appConfig.ScreenWidth,
        backgroundColor: "#33333344",
        marginBottom: -9
      },
      bottomContent: {
        width: appConfig.ScreenWidth,
        backgroundColor: "#FFF",
        borderTopLeftRadius: 9,
        borderTopRightRadius: 9,
        paddingTop: 15
      }
    });
    
    
  • 相关阅读:
    mysql中in 做条件匹配 带逗号的字符串 数据异常解决
    [LeetCode] Kth Largest Element in a Stream 数据流中的第K大的元素
    [LeetCode] Binary Search 二分搜索法
    [LeetCode] Search in a Sorted Array of Unknown Size 在未知大小的有序数组中搜索
    [LeetCode] Insert into a Binary Search Tree 二叉搜索树中插入结点
    [LeetCode] Search in a Binary Search Tree 二叉搜索树中搜索
    [LeetCode] Design Circular Deque 设计环形双向队列
    [LeetCode] Design Circular Queue 设计环形队列
    [LeetCode] N-ary Tree Preorder Traversal N叉树的前序遍历
    [LeetCode] 589. N-ary Tree Postorder Traversal N叉树的后序遍历
  • 原文地址:https://www.cnblogs.com/YooHoeh/p/12098872.html
Copyright © 2011-2022 走看看