当前位置: 移动技术网 > IT编程>开发语言>JavaScript > react native仿微信PopupWindow效果的实例代码

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

2017年12月12日  | 移动技术网IT编程  | 我要评论

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

实现思路分析:

要实现上面的视图,有很多种实现方式。前面的文章说过,要实现弹框相关的可以用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',
  },
});

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持移动技术网。

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网