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 轻松支持函数重载 (Part 2 - 实现)
Aug 04 Javascript
可以将word转成html的js代码
Apr 11 Javascript
jQuery代码优化 选择符篇
Nov 01 Javascript
jquery索引在使用中的一些困惑
Oct 24 Javascript
JS阻止冒泡事件以及默认事件发生的简单方法
Jan 17 Javascript
node.js中的fs.renameSync方法使用说明
Dec 16 Javascript
Bootstrap图片轮播组件使用实例解析
Jun 30 Javascript
Vue.js每天必学之指令系统与自定义指令
Sep 07 Javascript
Bootstrap表单使用方法详解
Feb 17 Javascript
vue+element-ui集成随机验证码+用户名+密码的form表单验证功能
Aug 05 Javascript
JavaScript中var的重要性实例分析
Jul 09 Javascript
javascript实现blob加密视频源地址的方法
Aug 08 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
PHP 面向对象程序设计(oop)学习笔记 (四) - 异常处理类Exception
2014/06/12 PHP
Centos下升级php5.2到php5.4全记录(编译安装)
2015/04/03 PHP
Composer设置忽略版本匹配的方法
2016/04/27 PHP
PHP有序表查找之二分查找(折半查找)算法示例
2018/02/09 PHP
php写入mysql中文乱码的实例解决方法
2019/09/17 PHP
Javascript miscellanea -display data real time, using window.status
2007/01/09 Javascript
jQuery实现点击该行即可删除HTML表格行
2014/10/17 Javascript
JavaScript数据类型详解
2015/04/01 Javascript
基于BootStrap Metronic开发框架经验小结【八】框架功能总体界面介绍
2016/05/12 Javascript
通过bootstrap全面学习less
2016/11/09 Javascript
EasyUI学习之DataGird分页显示数据
2016/12/29 Javascript
JavaScript 巧学巧用
2017/05/23 Javascript
Node.js 利用cheerio制作简单的网页爬虫示例
2018/03/01 Javascript
Angular5中提取公共组件之radio list的实例代码
2018/07/10 Javascript
nodejs 如何手动实现服务器
2018/08/20 NodeJs
10分钟彻底搞懂Http的强制缓存和协商缓存(小结)
2018/08/30 Javascript
webpack@v4升级踩坑(小结)
2018/10/08 Javascript
node实现分片下载的示例代码
2018/10/17 Javascript
vue 基于element-ui 分页组件封装的实例代码
2018/12/10 Javascript
JavaScript实现小球沿正弦曲线运动
2020/09/07 Javascript
python 文件操作删除某行的实例
2017/09/04 Python
彻彻底底地理解Python中的编码问题
2018/10/15 Python
python实现诗歌游戏(类继承)
2019/02/26 Python
Python利用requests模块下载图片实例代码
2019/08/12 Python
python爬虫 基于requests模块的get请求实现详解
2019/08/20 Python
Python实现语音识别和语音合成功能
2019/09/20 Python
详解如何修改python中字典的键和值
2020/09/29 Python
HTML5 Convas APIs方法详解
2015/04/24 HTML / CSS
详解HTML5 Canvas绘制时指定颜色与透明度的方法
2016/03/25 HTML / CSS
英国最大的独立摄影零售商:Park Cameras
2019/11/27 全球购物
俄罗斯汽车零件和配件在线商店:CarvilleShop
2019/11/29 全球购物
生物科学系大学生的自我评价
2013/12/20 职场文书
计算机专业毕业生自荐信
2013/12/31 职场文书
创文明城市标语
2014/06/16 职场文书
2015大学生党员自我评价范文
2015/03/03 职场文书
Python关于OS文件目录处理的实例分享
2021/05/23 Python