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初学者需要了解10个小技巧
Aug 25 Javascript
js中Math之random,round,ceil,floor的用法总结
Dec 26 Javascript
动态添加删除表格行的js实现代码
Feb 28 Javascript
javascript时间函数大全
Jun 30 Javascript
轻量级网页遮罩层jQuery插件用法实例
Jul 31 Javascript
AngularJs基于角色的前端访问控制的实现
Nov 07 Javascript
浅析Ajax语法
Dec 05 Javascript
Bootstrap jquery.twbsPagination.js动态页码分页实例代码
Feb 20 Javascript
详解用函数式编程对JavaScript进行断舍离
Sep 18 Javascript
vue 项目中使用Loading组件的示例代码
Aug 31 Javascript
vue源码nextTick使用及原理解析
Aug 13 Javascript
Vue.js 中制作自定义选择组件的代码附演示demo
Feb 28 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 保留字列表
2012/10/04 PHP
PHP实现微信支付(jsapi支付)流程步骤详解
2018/03/15 PHP
实现只能输入数字的input不用replace方法
2013/09/12 Javascript
利用毫秒减值计算时长的js代码
2013/09/22 Javascript
jQuery aminate方法定位到页面具体位置
2013/12/26 Javascript
使用javascript实现判断当前浏览器
2015/04/14 Javascript
JavaScript动态提示输入框输入字数的方法
2015/07/27 Javascript
JavaScript数据类型判定的总结笔记
2015/07/31 Javascript
全面解析Bootstrap手风琴效果
2020/04/17 Javascript
prototype框架中美元符号$用法分析
2016/01/22 Javascript
微信小程序教程之本地图片上传(leancloud)实例详解
2016/11/16 Javascript
简单实现node.js图片上传
2016/12/18 Javascript
JavaScript编写的网页小游戏,很给力
2017/08/18 Javascript
关于TypeScript模块导入的那些事
2018/06/12 Javascript
Vue事件修饰符native、self示例详解
2019/07/09 Javascript
js实现ajax的用户简单登入功能
2020/06/18 Javascript
跟老齐学Python之一个免费的实验室
2014/09/14 Python
python实现基于两张图片生成圆角图标效果的方法
2015/03/26 Python
Python的Tornado框架的异步任务与AsyncHTTPClient
2016/06/27 Python
Python黑帽编程 3.4 跨越VLAN详解
2016/09/28 Python
浅谈Python用QQ邮箱发送邮件时授权码的问题
2018/01/29 Python
Tensorflow的可视化工具Tensorboard的初步使用详解
2018/02/11 Python
python smtplib模块实现发送邮件带附件sendmail
2018/05/22 Python
Python后台开发Django会话控制的实现
2019/04/15 Python
树莓派极简安装OpenCv的方法步骤
2019/10/10 Python
python实现简单学生信息管理系统
2020/04/09 Python
解决echarts中饼图标签重叠的问题
2020/05/16 Python
python实现学生管理系统开发
2020/07/24 Python
CSS3实现苹果手机解锁的字体闪亮效果示例
2021/01/05 HTML / CSS
HTML5拖放API实现自动生成相框功能
2020/04/07 HTML / CSS
CheapTickets泰国:廉价航班,查看促销价格并预订机票
2019/12/28 全球购物
心理健康教育心得体会
2013/12/29 职场文书
50岁生日感言
2014/01/23 职场文书
总经理文秘岗位职责
2014/02/03 职场文书
导游词之镇江-金山寺
2019/10/14 职场文书
win10怎么设置右下角图标不折叠?Win10设置右下角图标不折叠的方法
2022/07/15 数码科技