React-Native导航条,相册,系统通讯录

调用手机通讯功能

这里我们用react-native-communications这个三方框架
  • 在HybridApp里实现这个功能还是挺麻烦的,需要客户端封装好接口给H5调用,但是在ReactNative里,一个组件就能搞定—— react-native-communications,安装请查看官方文档
    这个组件安装很简单,支持的功能有:拨号、发短信、发Email、打开网页 等 ,下面是官方一个综合的例子:
import React, { Component }  from 'react';
import {
  AppRegistry,
  StyleSheet,
  Text,
  View,
  TouchableOpacity
} from 'react-native';
import Communications from 'react-native-communications';
class RNCommunications extends Component({
  render() {
    return (
      <View style={styles.container}>
        <TouchableOpacity onPress={() => Communications.phonecall('0123456789', true)}>
          <View style={styles.holder}>
            <Text style={styles.text}>Make phonecall</Text>
          </View>
        </TouchableOpacity>
        <TouchableOpacity onPress={() => Communications.email(['emailAddress1', 'emailAddress2'],null,null,'My Subject','My body text')}>
          <View style={styles.holder}>
            <Text style={styles.text}>Send an email</Text>
          </View>
        </TouchableOpacity>
        <TouchableOpacity onPress={() => Communications.text('0123456789')}>
          <View style={styles.holder}>
            <Text style={styles.text}>Send a text/iMessage</Text>
          </View>
        </TouchableOpacity>
        <TouchableOpacity onPress={() => Communications.web('https://github.com/facebook/react-native')}>
          <View style={styles.holder}>
            <Text style={styles.text}>Open react-native repo on Github</Text>
          </View>
        </TouchableOpacity>
      </View>
    );
  }
});
const styles = StyleSheet.create({
  container: {
    flex: 1,
    alignItems: 'center',
    backgroundColor: 'rgb(253,253,253)',
  },
  holder: {
    flex: 0.25,
    justifyContent: 'center',
  },
  text: {
    fontSize: 32,
  },
});
AppRegistry.registerComponent('RNCommunications', () => RNCommunications);

访问手机相册

  • 调取手机相册和上传图片是个老生常谈的问题,ReactNative
    里可以通过react-native-image-picker来处理,安装请查看官方文档拎一段代码片段:
import ImagePicker from 'react-native-image-picker'
const options = {
    title: '选择上传图片', // specify null or empty string to remove the title
    cancelButtonTitle: '取消',
    takePhotoButtonTitle: '拍照...', // specify null or empty string to remove this button
    chooseFromLibraryButtonTitle: '从库中选择...', // specify null or empty string to remove this button
    //customButtons: {
    //    'Choose Photo from Facebook': 'fb', // [Button Text] : [String returned upon selection]
    //},
    cameraType: 'back', // 'front' or 'back'
    mediaType: 'photo',
    //videoQuality: 'high', // 'low', 'medium', or 'high'
    maxWidth: 200, // photos only
    maxHeight: 200, // photos only
    allowsEditing: true,
    noData: false,
}
//...
onUpload() {
        ImagePicker.showImagePicker(options, (response) => {
            if (response.didCancel) {
                //console.log('User cancelled image picker');
            }
            else if (response.error) {
                //console.log('ImagePicker Error: ', response.error);
            } else {
                let source = {uri: response.uri.replace('file://', ''), isLocal: true, isStatic: true};
                this.setState({ form: {...this.state.form, avatar: source} })
            }
        })
    }
``

![image.png](http://upload-images.jianshu.io/upload_images/2969114-475487f2dd4596b9.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

####模态框
- 模态框在App里使用的也比较多,比如确认模态、加载模态、输入模态等,出于良好的用户体验和兼容性考虑,我这里底层采用react-native-modalbox
,然后根据不同功能进行二次加工。
[](http://jafeney.com/2016/06/17/2016-06-17-react-native/#ConfirmModal)ConfirmModal

很常见,不多做介绍,copy下面代码 直接可以使用

import React, { Component } from 'react';
import {
Dimensions,
StyleSheet,
Text,
TouchableOpacity,
View,
} from 'react-native';
import ModalBox from 'react-native-modalbox';
const styles = StyleSheet.create({
modal: {
borderRadius: 10,
},
modalContent: {
flex: 1,
paddingLeft: 10,
paddingRight: 10,
},
h2: {
marginTop: 15,
fontSize: 20,
color: '#555',
textAlign: 'center',
},
modalOption: {
flexDirection: 'row',
borderTopWidth: 1,
borderTopColor: '#ddd',
},
modalCancel: {
flex: 1,
padding: 15,
},
modalCancelText: {
fontSize: 16,
textAlign: 'center',
},
modalConfirm: {
flex: 1,
padding: 15,
borderLeftWidth: 1,
borderLeftColor: '#ddd',
},
modalConfirmText: {
fontSize: 16,
textAlign: 'center',
},
message: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
messageText: {
color: '#555',
fontSize: 16,
},
});
export default class ConfirmModal extends Component {
constructor(props) {
super(props);
}
open() {
this.refs.modal.open()
}
close() {
this.refs.modal.close()
}
render() {
let { width } = Dimensions.get('window');
return (
<ModalBox
ref={"modal"}
style={[styles.modal, {width: this.props.width || (width-60), height: this.props.height || 200}]}
backdropOpacity={0.3}
position={"center"}
isOpen={false}>
<View style={styles.modalContent}>
<Text style={styles.h2}>{ this.props.title || '提示' }</Text>
<View style={styles.message}><Text style={styles.messageText}>{ this.props.message }</Text></View>
</View>
<View style={styles.modalOption}>
<TouchableOpacity style={styles.modalCancel} onPress={()=> this.refs.modal.close() }>
<Text style={styles.modalCancelText}>取消</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.modalConfirm} onPress={()=> this.props.onConfirm() }>
<Text style={styles.modalConfirmText}>确定</Text>
</TouchableOpacity>
</View>
</ModalBox>
)
}
}

LoadingModal

这个也很常见,copy下面代码 直接可以使用

import React, { Component } from 'react';
import {
StyleSheet,
} from 'react-native';
import ModalBox from 'react-native-modalbox';
const styles = StyleSheet.create({
modal: {
justifyContent: 'center',
alignItems: 'center',
backgroundColor: 'transparent'
},
});
export default class LoadingModal extends Component {
constructor(props) {
super(props);
}
open() {
this.refs.modal.open()
}
close() {
this.refs.modal.close()
}
render() {
return (
<ModalBox
style={styles.modal}
ref="modal"
position={"center"}
backdrop={false}
isOpen={this.props.isOpen || false}
//backdropOpacity={.3}
backdropPressToClose={false}
animationDuration={10}
>
</ModalBox>
);
}
}

####PickerModal

- 这个特别讲解一下,PickerModal用于页面上的Picker的处理,显示效果如下:

![image.png](http://upload-images.jianshu.io/upload_images/2969114-517be8b72ca2acb6.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

import React, { Component } from 'react';
import {
Dimensions,
StyleSheet,
Text,
TouchableOpacity,
Picker,
View,
} from 'react-native';
import ModalBox from 'react-native-modalbox'
import dismissKeyboard from '../mixins/dismiss-keyboard'
const styles = StyleSheet.create({
popup: {
},
popupContent: {
flex: 1,
paddingLeft: 10,
paddingRight: 10,
},
h2: {
marginTop: 15,
fontSize: 20,
color: '#555',
textAlign: 'center',
},
popupOption: {
flexDirection: 'row',
borderTopWidth: 1,
borderTopColor: '#ddd',
},
popupCancel: {
flex: 1,
padding: 15,
},
popupCancelText: {
fontSize: 16,
textAlign: 'center',
},
popupConfirm: {
flex: 1,
padding: 15,
borderLeftWidth: 1,
borderLeftColor: '#ddd',
},
popupConfirmText: {
fontSize: 16,
textAlign: 'center',
},
message: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
messageText: {
color: '#555',
fontSize: 16,
},
});
export default class PickerModal extends Component {
constructor(props) {
super(props);
}
open() {
dismissKeyboard()
this.refs.modal.open()
}
close() {
this.refs.modal.close()
}
_renderPickerItems(data) {
data.map((item)=>{
return [
<Picker.Item label={item[0]} value={item[1]} />
]
})
}
render() {
let { width } = Dimensions.get('window');
return (
<ModalBox
ref={"modal"}
style={[styles.popup, {width: this.props.width || (width), height: this.props.height || 200}]}
backdropOpacity={0.3}
position={"bottom"}
swipeToClose={false}
isOpen={false}>
<View style={styles.popupContent}>
<Picker {...this.props}>
{this.props.dataSource.map((item,i)=> {
if (item.length) return <Picker.Item key={i} label={item[0]} value={item[1]} />
})}
</Picker>
</View>
</ModalBox>
)
}
}

补充说明一下dismissKeyboard()这个方法,该方法用于关闭页面的keyboard(键盘),ReactNative 默认没有这种方法,需要自己编写:

import { TextInput } from 'react-native';
const { State: TextInputState } = TextInput;
export default function dismissKeyboard() {
TextInputState.blurTextInput(TextInputState.currentlyFocusedField());
}

####导航条

- 这个组件其实ReactNative提供了原生版本的,但是样式和功能上不好控制,建议自己手写一个,代码如下:

import React, { Component } from "react";
import {
Image,
Platform,
StyleSheet,
Text,
TouchableOpacity,
View,
} from 'react-native';
const styles = StyleSheet.create({
leftButton: {
marginLeft: 5,
},
rightButton: {
marginRight: 5,
},
button: {
width: 44,
height: 44,
justifyContent: 'center',
alignItems: 'center',
},
nav: {
backgroundColor: '#f9f9f9',
flexDirection: 'row',
alignItems: 'center',
},
title: {
flex: 1,
height: 44,
justifyContent: 'center',
},
btnText: {
fontSize: 16,
color: '#777',
},
marginForIOS: {
marginTop: 20,
},
titleText: {
fontSize: 20,
textAlign: 'center',
color: '#555'
}
});
export class RightButton extends Component {
render() {
return (
<TouchableOpacity
style={styles.button}
onPress={this.props.onPress}>
{ this.props.text ? <Text style={styles.btnText}>{this.props.text}</Text> : null }
{ this.props.icon ? <Image source={this.props.icon} style={styles.rightButton} /> : null }
</TouchableOpacity>
);
}
}
export class NavigatorBar extends Component {
_leftButton() {
if (this.props.navigator.getCurrentRoutes().length > 1) return (
<TouchableOpacity
style={styles.button}
onPress={()=> this.props.navigator.pop() }>
<Image source={require('../assets/icon-nav-left.png')} style={styles.leftButton} />
</TouchableOpacity>
)
}
_rightButton() {
if (this.props.rightButton) return (
<RightButton {...this.props.rightButton} />
)
}
render() {
return (
<View style={styles.nav}>
<View style={[styles.button, Platform.OS=='ios' ? styles.marginForIOS : null]}>
{this._leftButton()}
</View>
<View style={[styles.title, Platform.OS=='ios' ? styles.marginForIOS : null]}>
<Text style={styles.titleText}>{ this.props.name }</Text>
</View>
<View style={[styles.button, Platform.OS=='ios' ? styles.marginForIOS : null]}>
{this._rightButton()}
</View>
</View>
);
}
}

- 然后在[Container](http://lib.csdn.net/base/docker)里就可以使用了:

import { NavigatorBar } from '../components/navigator'

- 没有右侧按钮
<NavigatorBar name="登录" navigator={this.props.navigator} />

- 右侧按钮为图标

<NavigatorBar name="我的" navigator={this.props.navigator} rightButton={{onPress: ()=>{this.props.navigator.push({component: Setting})}, icon: require('../../assets/icon-set.png')}} />


- 右侧按钮为文字

<NavigatorBar name="我的订单" navigator={this.props.navigator} rightButton={{text: '历史 ', onPress: ()=> this.props.navigator.push({component: OrderHitory}) }} />


最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,445评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,889评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,047评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,760评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,745评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,638评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,011评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,669评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,923评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,655评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,740评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,406评论 4 320
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,995评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,961评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,023评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,483评论 2 342

推荐阅读更多精彩内容