欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

React Native实现地址挑选器功能

程序员文章站 2022-07-06 20:33:12
本文实例为大家分享了react native地址挑选器的实现代码,供大家参考,具体内容如下 产品经理:“你明白吧,这里向右划可以出菜单,然后需要一个闪烁的动画,还有,我想...

本文实例为大家分享了react native地址挑选器的实现代码,供大家参考,具体内容如下

产品经理:“你明白吧,这里向右划可以出菜单,然后需要一个闪烁的动画,还有,我想这个tab可以拉下来,你懂吧?

设计师:“别废话,把你要抄的产品给我看下。”


接下来,我们仿一下别人家的地址挑选器

React Native实现地址挑选器功能

import react, { component, proptypes } from 'react';
import {
 viewproptypes,
 stylesheet,
 view,
 touchableopacity,
 touchablenativefeedback,
 platform,
 animated,
 text
} from 'react-native';

export default class selectcitytabbar extends component {
 //属性声名
 static proptypes = {
  gotopage: proptypes.func,
  activetab: proptypes.number,
  tabs: proptypes.array,
  backgroundcolor: proptypes.string,
  activetextcolor: proptypes.string,
  inactivetextcolor: proptypes.string,
  textstyle: text.proptypes.style,
  tabstyle: viewproptypes.style,
  rendertab: proptypes.func,
  underlinestyle: viewproptypes.style,
 };
 //默认属性
 static defaultprops = {
  activetextcolor: '#fa3d4f',
  inactivetextcolor: 'black',
  backgroundcolor: null,
 }

 rendertab(name, page, istabactive, onpresshandler) {
  const { activetextcolor, inactivetextcolor, textstyle, } = this.props;
  const textcolor = istabactive ? activetextcolor : inactivetextcolor;
  const fontweight = istabactive ? 'bold' : 'normal';
  const viewstyle = istabactive ? [styles.tab, { borderbottomwidth: constant.sizedividerlarge, bordercolor: constant.colorprimary }] : styles.tab;

  if (platform.os !== 'ios') {
   return <touchablenativefeedback
    delaypressin={0}
    background={touchablenativefeedback.selectablebackground()}
    key={name + page}
    accessible={true}
    accessibilitylabel={name}
    accessibilitytraits='button'
    onpress={() => onpresshandler(page)}
   >
    <view style={viewstyle}>
     <text style={[{ color: textcolor, fontweight, }, textstyle,]}>
      {name}
     </text>
    </view>
   </touchablenativefeedback>
  }

  return <touchableopacity
   key={name + page}
   accessible={true}
   accessibilitylabel={name}
   accessibilitytraits='button'
   onpress={() => onpresshandler(page)}
  >
   <view style={viewstyle}>
    <text style={[{ color: textcolor, fontweight, }, textstyle,]}>
     {name}
    </text>
   </view>
  </touchableopacity>;
 }

 render() {
  return (
   <view style={{ flexdirection: 'row', borderbottomwidth: constant.sizedividernormal, bordercolor: constant.colordivider }}>
    {this.props.tabs.map((name, page) => {
     const istabactive = this.props.activetab === page;
     const rendertab = this.props.rendertab || this.rendertab;
     return this.rendertab(name, page, istabactive, this.props.gotopage);
    })}
   </view>
  );
 }
}



const styles = stylesheet.create({
 tab: {
  alignitems: 'center',
  justifycontent: 'center',
  paddingbottom: 10,
  marginleft: 10,
 },
 tabs: {
  height: 50,
  flexdirection: 'row',
  justifycontent: 'space-around',
  borderwidth: 1,
  bordertopwidth: 0,
  borderleftwidth: 0,
  borderrightwidth: 0,
  bordercolor: '#ccc',
 },
});

npm react-native-scrollable-tab-view 组件

import react, { component } from 'react';
import {
 stylesheet,
 view,
 scrollview,
 dimensions,
 touchableopacity,
 interactionmanager,
 platform,
 uimanager,
 text
} from 'react-native';
import scrollabletabview from 'react-native-scrollable-tab-view';
import selectcitytabbar from './selectcitytabbar'
import area_json from '../../util/area.json';
const { height, width } = dimensions.get('window');

export default class addressselect extends component {

 static defaultprops = {
  commitfun: function (value) {
   console.log(value);
  },
  dissmissfun: function () {

  },
  lastaddress: null,
 };

 constructor(props) {
  super(props);
  if (platform.os === 'android') {
   uimanager.setlayoutanimationenabledexperimental(true)
  }
  const { lastaddress } = props;
  let selectaddress = this.initaddress(lastaddress);
  this.state = {
   selectaddress
  }
 }

 initaddress(lastaddress) {
  let selectaddress = [
   {
    value: null,
    label: null,
    children: area_json,
   }, {
    value: null,
    label: null,
    children: null,
   }, {
    value: null,
    label: null,
    children: null,
   }];
  let array = null;

  function fun(array, value) {
   for (let item of array) {
    if (item.value + '' === value + '') {
     return item;
    }
   }
  }
  try {
   selectaddress = selectaddress.map((item, index) => {
    let result = fun(array ? array : area_json, lastaddress[index].value);
    if (result.children) {
     array = result.children;
    }
    return result;
   });
  } catch (e) {
   console.log('-----e-', e);
  }
  return selectaddress
 }


 /**
  * 列表行
  * @param item
  * @param i
  * @returns {xml}
  */
 renderlistitem(item, i) {
  let itemstyle = styles.itemstyle;
  let textstyle = styles.itemtext;
  let { selectaddress } = this.state;
  if (item.label === selectaddress[i].label) {
   itemstyle = [itemstyle];
   textstyle = [textstyle, { color: 'red' }]
  }
  return (
   <touchableopacity
    style={itemstyle}
    key={i + item.label}
    onpress={() => {
     this.pressitem(item, i)
    }}
   >
    <text style={textstyle}>{item.label}</text>
   </touchableopacity>
  )
 }

 /**
  * 点击列表事件
  * @param item 选中数据
  * @param i 选中行数
  */
 pressitem(item, i) {
  let { selectaddress } = this.state;
  const initobj = {
   value: null,
   label: null,
   children: null,
  }
  let tempindex = 0;
  if (i === 0) {
   selectaddress[0] = item;
   selectaddress[1] = initobj;
   selectaddress[2] = initobj;
   tempindex = 1
  } else if (i === 1) {
   selectaddress[1] = item;
   selectaddress[2] = initobj;
   tempindex = 2
  } else {
   selectaddress[2].value = item.value;
   selectaddress[2].label = item.label;
   tempindex = 2
   let address = [
    {
     label: selectaddress[0].label,
     value: selectaddress[0].value
    },
    {
     label: selectaddress[1].label,
     value: selectaddress[1].value
    },
    {
     label: selectaddress[2].label,
     value: selectaddress[2].value
    }
   ]
   this.props.commitfun && this.props.commitfun(address);
   this.props.dissmissfun && this.props.dissmissfun();
   return null;

  }
  this.setstate({ selectaddress });
  interactionmanager.runafterinteractions(() => {
   this.tabview.gotopage(tempindex)
  })

 }

 render() {
  const { selectaddress } = this.state;
  return (
   <view style={styles.container}>
    <view style={{ width: width, height: 40, flexdirection: 'row', justifycontent: 'center', alignitems: 'center', }}>
     <text>所在地区</text>
    </view>
    <scrollabletabview
     ref={(tabview) => {
      this.tabview = tabview;
     }}
     rendertabbar={() => <selectcitytabbar />}
    >
     {selectaddress.map((obj, i) => {
      let array = (i === 0) ? area_json : selectaddress[i - 1].children;
      if (array) {
       return (
        <scrollview
         key={i}
         tablabel={obj.label || '请选择'}
         style={styles.scrollstylelist}
        >
         {array && array.map((obj2, j) => {
          return this.renderlistitem(obj2, i)
         })}
        </scrollview>
       )
      }
     })}
    </scrollabletabview>
   </view>
  );
 }
}

const styles = stylesheet.create({
 container: {
  height: height * 0.6,
  backgroundcolor: '#f5fcff',
 },
 scrollstylelist: {
  width: width,
  marginbottom: constant.sizemargindefault,
  margintop: constant.sizemargindefault,
 },
 itemstyle: {
  margintop: 5,
  width: width,
  height: 35,
  marginleft: constant.sizemargindefault,
  justifycontent: 'center'
 },
 itemtext: {
  fontsize: 15,
  color: '#333333'
 },

使用方法:

import react, {component} from 'react';
import {
 stylesheet,
 view,
 touchableopacity,
 alert,
 scrollview,
 art,
 touchablehighlight,
 listview,
 dimensions,
 text
} from 'react-native';

import {reactnavcomponent, widget} from 'rn-yunxi';
import addressselect from '../../app-widget/address-select/index'

export default class extends react.component {

 render() {
  return (
   <touchableopacity style={{flex:1, justifycontent:'center', alignitems:'center'}} onpress={() => this.openaddressselect()}>
    <text >地址选择</text>
   </touchableopacity>
  );

 }

 openaddressselect() {

  widget.popup.show( // 这边使用自己封装的modal嵌套地址选择器
   <addressselect
    commitfun={(area) => this.onselectarea(area)}
    dissmissfun={() => widget.popup.hide()}
   />,
   {
    animationtype: 'slide-up', backgroundcolor: '#00000000', onmaskclose: () => {
    widget.popup.hide()
   }
   })
 }

 onselectarea = (area) => {
  log(area)
 }
};

数据类型格式

[
 {
  "value": "110000000000",
  "children": [
   {
    "value": "110100000000",
    "children": [
     {
      "value": "110101000000",
      "label": "东城区"
     },
     {
      "value": "110102000000",
      "label": "西城区"
     },
     {
      "value": "110105000000",
      "label": "朝阳区"
     },
     {
      "value": "110106000000",
      "label": "丰台区"
     },
     {
      "value": "110107000000",
      "label": "石景山区"
     },
     {
      "value": "110108000000",
      "label": "海淀区"
     },
     {
      "value": "110109000000",
      "label": "门头沟区"
     },
     {
      "value": "110111000000",
      "label": "房山区"
     },
     {
      "value": "110112000000",
      "label": "通州区"
     },
     {
      "value": "110113000000",
      "label": "顺义区"
     },
     {
      "value": "110114000000",
      "label": "昌平区"
     },
     {
      "value": "110115000000",
      "label": "大兴区"
     },
     {
      "value": "110116000000",
      "label": "怀柔区"
     },
     {
      "value": "110117000000",
      "label": "平谷区"
     },
     {
      "value": "110118000000",
      "label": "密云区"
     },
     {
      "value": "110119000000",
      "label": "延庆区"
     }
    ],
    "label": "北京市"
   }
  ],
  "label": "北京市"
 }
]



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