React Native實(shí)現(xiàn)地址挑選器功能
本文實(shí)例為大家分享了React Native地址挑選器的實(shí)現(xiàn)代碼,供大家參考,具體內(nèi)容如下
產(chǎn)品經(jīng)理:“你明白吧,這里向右劃可以出菜單,然后需要一個(gè)閃爍的動(dòng)畫,還有,我想這個(gè)tab可以拉下來,你懂吧?
設(shè)計(jì)師:“別廢話,把你要抄的產(chǎn)品給我看下。”
…
接下來,我們仿一下別人家的地址挑選器
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, }; //默認(rèn)屬性 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> ) } /** * 點(diǎn)擊列表事件 * @param item 選中數(shù)據(jù) * @param i 選中行數(shù) */ 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>所在地區(qū)</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 || '請(qǐng)選擇'} 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) } };
數(shù)據(jù)類型格式
[ { "value": "110000000000", "children": [ { "value": "110100000000", "children": [ { "value": "110101000000", "label": "東城區(qū)" }, { "value": "110102000000", "label": "西城區(qū)" }, { "value": "110105000000", "label": "朝陽區(qū)" }, { "value": "110106000000", "label": "豐臺(tái)區(qū)" }, { "value": "110107000000", "label": "石景山區(qū)" }, { "value": "110108000000", "label": "海淀區(qū)" }, { "value": "110109000000", "label": "門頭溝區(qū)" }, { "value": "110111000000", "label": "房山區(qū)" }, { "value": "110112000000", "label": "通州區(qū)" }, { "value": "110113000000", "label": "順義區(qū)" }, { "value": "110114000000", "label": "昌平區(qū)" }, { "value": "110115000000", "label": "大興區(qū)" }, { "value": "110116000000", "label": "懷柔區(qū)" }, { "value": "110117000000", "label": "平谷區(qū)" }, { "value": "110118000000", "label": "密云區(qū)" }, { "value": "110119000000", "label": "延慶區(qū)" } ], "label": "北京市" } ], "label": "北京市" } ]
以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
react路由v6版本NavLink的兩個(gè)小坑及解決
這篇文章主要介紹了react路由v6版本NavLink的兩個(gè)小坑及解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-10-10React?數(shù)據(jù)共享useContext的實(shí)現(xiàn)
本文主要介紹了React?數(shù)據(jù)共享useContext的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-04-04React?antd中setFieldsValu的簡便使用示例代碼
form.setFieldsValue是antd?Form組件中的一個(gè)方法,用于動(dòng)態(tài)設(shè)置表單字段的值,它接受一個(gè)對(duì)象作為參數(shù),對(duì)象的鍵是表單字段的名稱,值是要設(shè)置的字段值,這篇文章主要介紹了React?antd中setFieldsValu的簡便使用,需要的朋友可以參考下2023-08-08React使用有限狀態(tài)機(jī)的實(shí)現(xiàn)示例
本文主要介紹了React使用有限狀態(tài)機(jī)的實(shí)現(xiàn)示例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-05-05ReactNative?狀態(tài)管理redux使用詳解
這篇文章主要介紹了ReactNative?狀態(tài)管理redux使用詳解2023-03-03react.js CMS 刪除功能的實(shí)現(xiàn)方法
下面小編就為大家?guī)硪黄猺eact.js CMS 刪除功能的實(shí)現(xiàn)方法。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-04-04webpack打包react項(xiàng)目的實(shí)現(xiàn)方法
這篇文章主要介紹了webpack打包react項(xiàng)目的實(shí)現(xiàn)方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-06-06