React Native實(shí)現(xiàn)地址挑選器功能
本文實(shí)例為大家分享了React Native地址挑選器的實(shí)現(xiàn)代碼,供大家參考,具體內(nèi)容如下
產(chǎn)品經(jīng)理:“你明白吧,這里向右劃可以出菜單,然后需要一個(gè)閃爍的動(dòng)畫(huà),還有,我想這個(gè)tab可以拉下來(lái),你懂吧?
設(shè)計(jì)師:“別廢話,把你要抄的產(chǎn)品給我看下?!?
…
接下來(lái),我們仿一下別人家的地址挑選器

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ù)類(lèi)型格式
[
{
"value": "110000000000",
"children": [
{
"value": "110100000000",
"children": [
{
"value": "110101000000",
"label": "東城區(qū)"
},
{
"value": "110102000000",
"label": "西城區(qū)"
},
{
"value": "110105000000",
"label": "朝陽(yáng)區(qū)"
},
{
"value": "110106000000",
"label": "豐臺(tái)區(qū)"
},
{
"value": "110107000000",
"label": "石景山區(qū)"
},
{
"value": "110108000000",
"label": "海淀區(qū)"
},
{
"value": "110109000000",
"label": "門(mén)頭溝區(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": "北京市"
}
]
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
react路由v6版本NavLink的兩個(gè)小坑及解決
這篇文章主要介紹了react路由v6版本NavLink的兩個(gè)小坑及解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-10-10
React?數(shù)據(jù)共享useContext的實(shí)現(xiàn)
本文主要介紹了React?數(shù)據(jù)共享useContext的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-04-04
React?antd中setFieldsValu的簡(jiǎn)便使用示例代碼
form.setFieldsValue是antd?Form組件中的一個(gè)方法,用于動(dòng)態(tài)設(shè)置表單字段的值,它接受一個(gè)對(duì)象作為參數(shù),對(duì)象的鍵是表單字段的名稱(chēng),值是要設(shè)置的字段值,這篇文章主要介紹了React?antd中setFieldsValu的簡(jiǎn)便使用,需要的朋友可以參考下2023-08-08
React使用有限狀態(tài)機(jī)的實(shí)現(xiàn)示例
本文主要介紹了React使用有限狀態(tài)機(jī)的實(shí)現(xiàn)示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-05-05
ReactNative?狀態(tài)管理redux使用詳解
這篇文章主要介紹了ReactNative?狀態(tài)管理redux使用詳解2023-03-03
react.js CMS 刪除功能的實(shí)現(xiàn)方法
下面小編就為大家?guī)?lái)一篇react.js CMS 刪除功能的實(shí)現(xiàn)方法。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-04-04
webpack打包react項(xiàng)目的實(shí)現(xiàn)方法
這篇文章主要介紹了webpack打包react項(xiàng)目的實(shí)現(xiàn)方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-06-06

