react native仿微信PopupWindow效果的实例代码


Posted in Javascript onAugust 07, 2017

在原生APP开发中,相信很多开发者都会见到这种场景:点击右上角更多的选项,弹出一个更多界面供用户选择。这种控件在原生开发中Android可以用PopupWindow实现,在iOS中可以用CMPopTipView,也可以自己写一个View实现。其类似的效果如下图所示:

react native仿微信PopupWindow效果的实例代码

实现思路分析:

要实现上面的视图,有很多种实现方式。前面的文章说过,要实现弹框相关的可以用React Native 提供的 Modal组件(Modal组件),使用Modal组件可以实现我们原生开发中的大多数效果。

要实现下拉三角,可以让美工切一个带下拉三角的背景,当然也可以自己通过ART实现(ART绘制)。对于选项卡的内容,在原生开发中为了适应更多的场景,我们一般会选择使用ListView组件,然后当点击某个Item的时候获得相应的属性即可。为了控制Modal的显示与消失,我们可以给Modal内置一个isVisible: this.props.show状态。

源码

要实现上面的效果,会这涉及到三个js文件:MorePopWidows.js、Utils.js、HomeActionBar.js,按照先后顺序,代码如下:

Utils.js

import {Dimensions} from 'react-native'

const deviceH = Dimensions.get('window').height
const deviceW = Dimensions.get('window').width

const basePx = 375

export default function px2dp(px) { 
  return px * deviceW / basePx
}

MorePopWidows.js

import React from 'react'
import {
  StyleSheet,
  Platform,
  View,
  Text,
  Image,
  TouchableOpacity,
  Alert,
  Modal,
  Dimensions,
} from 'react-native'
import SpacingView from "./SpacingView";
import QRScanPage from "../home/QRScanPage";

const { width, height } = Dimensions.get('window');
import px2dp from '../util/Utils'

const mTop = px2dp(Platform.OS == "ios" ? 64 : 44)

let mwidth = 95;
let mheight = 100;
const marginTop = mTop;

export default class MorePopWidows extends React.Component {

  constructor(props) {
    super(props);
    this.state = {
      isVisible: this.props.show,
    }
    mwidth = this.props.width ;
    mheight = this.props.height ;
  }

  componentWillReceiveProps(nextProps) {
    this.setState({ isVisible: nextProps.show });
  }

  closeModal() {
    this.setState({
      isVisible: false
    });
    this.props.closeModal(false);
  }

  scan() {
    this.props.navigator.push({
      component: QRScanPage,
    })
  }

  render() {
    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()}>

         <View style={styles.modal}>
          <TouchableOpacity activeOpacity={1} onPress={this.scan.bind(this)} style={styles.itemView}>
           <Image style={styles.imgStyle} source={require('../images/ic_scan_code_white.png')} />
           <Text style={styles.textStyle}>扫一扫</Text>
          </TouchableOpacity>
           <SpacingView/>
          <TouchableOpacity activeOpacity={1} onPress={() => Alert.alert('点击了付款码')} style={styles.itemView}>
           <Image style={styles.imgStyle} source={require('../images/ic_code_white.png')} />
           <Text style={styles.textStyle}>付款码</Text>
          </TouchableOpacity>
         </View>
        </TouchableOpacity>
       </Modal>
      </View>
    )
  }
}
const styles = StyleSheet.create({
  container: {
    width: width,
    height: height,
  },
  modal: {
    backgroundColor: '#696969',
    width: mwidth,
    height: mheight,
    position: 'absolute',
    left: width - mwidth - 10,
    top: marginTop,
    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: 20,
    height: 20,
  }
});

最后是在代码中使用MorePopWidows的代码:

HomeActionBar.js

/**
 * https://github.com/facebook/react-native
 * @flow 首页的标题栏
 */

import React, {Component} from 'react';
import {Platform, View, Dimensions, Text, StyleSheet, TouchableOpacity, Image} from 'react-native';
import SelectCityPage from '../home/SelectCityPage'
import MorePopWidows from '../component/MorePopWidows'
import px2dp from '../util/Utils'

const isIOS = Platform.OS == "ios"
const {width, height} = Dimensions.get('window')
const headH = px2dp(isIOS ? 64 : 44)

export default class HomeActionBar extends Component {

  constructor(props) {
    super(props);
    this.state = {
      showPop: false,
    }
  }

  city() {
    this.props.navigator.push({
      component: SelectCityPage,
    })
  }

  renderHeader() {
    return (
      <View >
      <View style={styles.headerStyle}>
        <TouchableOpacity style={styles.action} onPress={this.city.bind(this)}>
          <Text style={styles.text}>上海</Text>
          <Image
            source={require('../images/ic_arrow_down.png')}/>
        </TouchableOpacity>
        <TouchableOpacity style={styles.searchBar}>
          <Image source={require('../images/ic_search.png')} style={styles.iconStyle}/>
          <Text style={{fontSize: 13, color: "#666", marginLeft: 5}}>输入商家、商品名称</Text>
        </TouchableOpacity>
        <TouchableOpacity style={styles.action} onPress={() => { this.setState({ showPop: !this.state.showPop }) }}>
          <Image style={styles.scanIcon}
              source={require('../images/ic_scan_code_white.png')}/>
          <Text style={styles.scanText}>扫码</Text>
        </TouchableOpacity>
      </View>
        <View style={{ position: 'absolute', top: headH, left: 0, width: width, height: height }}>
          <MorePopWidows width={90} height={100} show={this.state.showPop} closeModal={(show) => {
            this.setState({showPop: show})
          }} {...this.props}/>
        </View>

      </View>
    )
  }

  render() {
    return (
      <View>
        {this.renderHeader()}
      </View>
    );
  }
}

const styles = StyleSheet.create({
  headerStyle: {
    backgroundColor: "#06C1AE",
    height: headH,
    paddingTop: px2dp(isIOS ? 20 : 0),
    paddingHorizontal: 16,
    flexDirection: 'row',
    alignItems: 'center',
  },
  searchBar: {
    width: width * 0.65,
    height: 30,
    borderRadius: 19,
    marginLeft: 10,
    flexDirection: 'row',
    justifyContent: 'flex-start',
    alignItems: 'center',
    backgroundColor: 'white',
    alignSelf: 'center',
    paddingLeft: 10,
  },
  text: {
    fontSize: 16,
    color: '#ffffff',
    justifyContent: 'center',
  },
  iconStyle: {
    width: 22,
    height: 22,
  },
  action: {
    flexDirection: 'row',
    justifyContent: 'center',
    alignItems: 'center',
  },
  scanIcon: {
    width: 28,
    height: 28,
    alignItems: 'center',
    marginLeft: 10,
  },
  scanText: {
    fontSize: 14,
    color: '#ffffff',
    justifyContent: 'center',
    alignItems: 'center',
  },
});

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
javascript下数值型比较难点说明
Jun 07 Javascript
jquery分页插件AmSetPager(自写)
Apr 15 Javascript
异步动态加载js与css文件的js代码
Sep 15 Javascript
js获取IP地址的方法小结
Jul 01 Javascript
node.js中的fs.exists方法使用说明
Dec 17 Javascript
js判断某个方法是否存在实例代码
Jan 10 Javascript
Javascript中数组方法汇总(推荐)
Apr 01 Javascript
封装的dialog插件 基于bootstrap模态对话框的简单扩展
Aug 10 Javascript
原生JS实现图片懒加载(lazyload)实例
Jun 13 Javascript
Vue+Element使用富文本编辑器的示例代码
Aug 14 Javascript
vue解决弹出蒙层滑动穿透问题的方法
Sep 22 Javascript
echarts饼图各个板块之间的空隙如何实现
Dec 01 Javascript
jquery+css实现简单的图片轮播效果
Aug 07 #jQuery
bootstrap table表格客户端分页实例
Aug 07 #Javascript
基于JS递归函数细化认识及实用实例(推荐)
Aug 07 #Javascript
react native实现往服务器上传网络图片的实例
Aug 07 #Javascript
使用Node.js实现简易MVC框架的方法
Aug 07 #Javascript
ES6新增的math,Number方法
Aug 06 #Javascript
ComboBox(下拉列表框)通过url加载调用远程数据的方法
Aug 06 #Javascript
You might like
一个基于PDO的数据库操作类(新) 一个PDO事务实例
2011/07/03 PHP
PHP 获取MySQL数据库里所有表的实现代码
2011/07/13 PHP
php多层数组与对象的转换实例代码
2013/08/05 PHP
PHP+MYSQL中文乱码问题
2015/07/01 PHP
PHP5.5迭代生成器用法实例详解
2016/03/16 PHP
php类的自动加载操作实例详解
2016/09/28 PHP
老生常谈php 正则中的i,m,s,x,e分别表示什么
2017/03/02 PHP
php装饰者模式简单应用案例分析
2019/10/23 PHP
JavaScript 工具库 Cloudgamer JavaScript Library v0.1 发布
2009/10/29 Javascript
JavaScript中“过于”犀利地for/in循环使用示例
2013/10/22 Javascript
jQuery+easyui中的combobox实现下拉框特效
2015/02/27 Javascript
深入理解JavaScript系列(28):设计模式之工厂模式详解
2015/03/03 Javascript
轻松学习jQuery插件EasyUI EasyUI创建树形网络(1)
2015/11/30 Javascript
详解Jquery的事件操作和文档操作
2016/12/19 Javascript
bootstrap弹出层的多种触发方式
2017/05/10 Javascript
gulp教程_从入门到项目中快速上手使用方法
2017/09/14 Javascript
JavaScript解决浮点数计算不准确问题的方法分析
2018/07/09 Javascript
vue+element加入签名效果(移动端可用)
2019/06/17 Javascript
Python验证码识别的方法
2015/07/10 Python
python3 打印输出字典中特定的某个key的方法示例
2019/07/06 Python
Python控制鼠标键盘代码实例
2020/12/08 Python
python 基于DDT实现数据驱动测试
2021/02/18 Python
德国箱包网上商店:koffer24.de
2016/07/27 全球购物
美国购买体育、音乐会和剧院门票网站:SelectATicket
2019/09/08 全球购物
JD Sports荷兰:英国领先的运动时尚零售商
2020/03/13 全球购物
高一英语教学反思
2014/01/22 职场文书
学生会招新策划书
2014/02/14 职场文书
庆元旦迎新年广播稿
2014/02/18 职场文书
护理专业自荐信范文
2014/02/26 职场文书
恶搞卫生巾广告词
2014/03/18 职场文书
求职者怎样写自荐信
2014/04/13 职场文书
意外死亡赔偿协议书
2014/10/14 职场文书
前台接待岗位职责范本
2015/04/03 职场文书
用Java实现简单计算器功能
2021/07/21 Java/Android
Kubernetes部署实例并配置Deployment、网络映射、副本集
2022/04/01 Servers
Vue操作Storage本地化存储
2022/04/29 Vue.js