本篇主要介绍: 
1. 自定义组件 
2. Alert 对话框

自定义对话框

之前的我都是利用React Native提供的基础组件对它们进行排列组合, 其实自定义也很简单, 我们还是拿上一篇文章的例子进行扩展。

当我们点击注册的时候,可以弹出一个对话框,让用户确认一下,如下图:

接下来就来试试, 
首先在项目目录下创建ConfirmDialog.js 
代码如下:

import React, { Component } from 'react';
import {
StyleSheet,
Text, // RN提供的组件
View,
BackAndroid
} from 'react-native';
import LoadMoreFooter from "./LoadMoreFooter"; let Dimensions = require('Dimensions');
let totalWidth = Dimensions.get('window').width;//宽
let totalHeight = Dimensions.get('window').height;//高 // 直接导出组件,不用写 module.exports=ConfirmDialog;了
export default class ConfirmDialog extends Component { constructor(props) {
super(props);
} render() {
alert('sasas');
// onPress事件直接与父组件传递进来的属性挂接
//numberOfLines 可显示3行
// {'\r\n'}确 定 回车换行后跟着确定,为了克服Text组件不能垂直居中显示
if(1){
return (
<View style={styles.confirmCont}>
<View style={styles.dialogStyle}>
<Text style={styles.textPrompt}>
{this.props.promptToUser}
</Text> <Text style={styles.cancelButton}
onPress={this.props.userCanceled}
numberOfLines={3}>
{'\r\n'}取 消 2222
</Text>
</View>
</View>
);
}
else { return (
<View style={styles.confirmCont}>
<View style={styles.dialogStyle}>
<Text style={styles.textPrompt}>
{this.props.promptToUser}
</Text>
<Text style={styles.yesButton}
onPress={this.props.userConfirmed}
numberOfLines={3}>
{'\r\n'}确 定 111
</Text> </View>
</View>
);
} }
} const styles = StyleSheet.create({
confirmCont: { //全屏显示 半透明 可以看到之前的控件但是不能操作了
position:'absolute', //声明绝对定位
top:0,
width:totalWidth,
height:totalHeight,
backgroundColor:'rgba(52,52,52,0.5)' //rgba a0-1 其余都是十进制数
},
dialogStyle: {
position:'absolute',
left:totalWidth/10, // 定义Dilaog起点位置
top:totalHeight*0.4,
width:totalWidth*0.8,
height:totalHeight*0.3,
backgroundColor:'white'
},
textPrompt: {
position:'absolute',
top:10,
left:10,
fontSize:20,
color:'black'
},
yesButton: {
position:'absolute',
bottom:10,
left:10,
width:totalWidth*0.35,
height:totalHeight*0.12,
backgroundColor:'grey',
fontSize:20,
color:'white',
textAlign:'center'
},
cancelButton: {
position:'absolute',
bottom:10,
right:10,
width:totalWidth*0.35,
height:totalHeight*0.12,
backgroundColor:'grey',
fontSize:20,
color:'white',
textAlign:'center'
}
});
/**
* Sample React Native App
* https://github.com/facebook/react-native
* @flow
*/ import React, { Component } from 'react';
import {
AppRegistry,
StyleSheet,
Text,
Image,
Dimensions,
TouchableOpacity,
TextInput,
ScrollView,
Keyboard,
Alert,
InteractionManager,
View
} from 'react-native';
import JPushModule from 'jpush-react-native';
import Main from './../../pages/main';
import Spinner from 'react-native-spinkit';
import { LOGIN_URL } from '../../component/Urls';
import { Login_Url } from '../../component/NewUrls';
import { timeoutPromise } from './../../component/TimeoutRequest';
import MDG from './../../component/ConfirmDialog';
var DeviceInfo = require('react-native-device-info');
import * as networkRequest from 'react-native-networkrequest'
var {height, width, scale, fontScale} = Dimensions.get('window');
// const instance = this;
var loading = false
class LoginNew extends Component {
constructor(props) {
super(props);
const {navigator} = this.props;
this.username = '';
this.password = '';
this.state = {
visible: false,
canLogin: true,
};
// load
storage.load({
key: 'userInfo',
id: '1001'
}).then(ret => {
this.username = ret.username;
this.password = ret.password;
this.token = ret.token;
this.userInfo = ret.userInfo;
if (navigator) {
this.props.navigator.replace({
name: 'Main',
params: {
token: DeviceInfo.getUniqueID(),
username: this.username,
password: this.password,
userInfo: this.userInfo,
badge: this.props.navigator.props.initialRoute.badge,
}
})
} }).catch(err => {
switch (err.name) {
case 'NotFoundError':
// TODO
break;
case 'ExpiredError':
// TODO
break;
}
});
} componentWillMount() { }
componentDidMount() {
InteractionManager.runAfterInteractions(() => {
this.setState({renderPlaceholderOnly: false});
});
}
componentWillUnmount() {
this.timeout && clearTimeout(this.timeout);
} render() {
return ( <View style={{ flexDirection: 'row',
flex:1,
borderBottomColor: 'lightgray',
borderBottomWidth: 1,
marginLeft: 30,
marginRight: 30,
marginTop: 10,
backgroundColor: '#FFFFFF',
shadowColor: '#ccc',
shadowOffset: {width: 1, height: 1},
shadowOpacity: 0.5,
shadowRadius: 1,
//justifyContent: 'center',
alignItems: 'center',
backgroundColor:'yellow'}}>
<MDG style={ {flex: 1, backgroundColor:'yellow'}} userConfirmed={this.userConfirmed}
userCanceled={this.userCanceled}
promptToUser={'使用'+this.state.inputedNum+'号码登录?'}/> </View> );
} forgetPassword(navigator) {
//const {navigator} = this.props;
if (navigator) {
navigator.push({
name: 'ForgetPassword', })
}
} forgetPassword(navigator) {
if (navigator) {
navigator.push({
name: 'ForgetPassword', })
}
}
fetchDataWithURl(url,body=null) {
if (!loading) {
loading = true
return timeoutPromise(20000,fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'text/html;charset=utf-8',
},
body: JSON.stringify(body)
}))
.then((response) =>{
if (response.status == '200') {
return response.json()
}else {
return response
}
})
.then((responseJson) => { //Alert.alert('提示',`ceshi 100000`) loading = false
if (responseJson.status&&responseJson.status != '200') {
Alert.alert('提示',`网络错误,错误原因${responseJson.status}`)
return
}
console.log(responseJson);
this.setState({
visible: false,
canLogin: true,
})
switch (responseJson.resultCode) {
case 0:
// 设置推送别名
JPushModule.setAlias('paike',()=>{},()=>{})
JPushModule.setTags([this.username],()=>{},()=>{})
// 登陆成功以后 储存用户信息
storage.save({
key: 'userInfo', //注意:请不要在key中使用_下划线符号!
id: '1001',
rawData: {
username: this.username,
password: this.password,
token: DeviceInfo.getUniqueID(),
},
// 如果不指定过期时间,则会使用defaultExpires参数
// 如果设为null,则永不过期
expires: null,
});
const {navigator} = this.props;
if (navigator) {
navigator.replace({
name: 'Main',
params: {
// token: DeviceInfo.getUniqueID(),
username: this.username,
password: this.password,
// userInfo: responseJson.data.list[0],
}
})
}
break;
case 2:
Alert.alert('提示','登陆失败,用户名不存在!')
break;
case 1:
Alert.alert('提示','登陆失败,用户名或密码错误!')
break;
default:
Alert.alert('提示','登陆失败,未知错误!')
} })
.catch((error) => { // console.error(error);
this.timeout = setTimeout(
()=>{
loading = false
Alert.alert('提示','请求超时,请重试',[
{text: '确定', onPress: () => {}},
]);
},50)
// this.setState({visible: false});
});
// networkRequest.Post(20000,url,(responseData)=>{
// loading = false
// if (responseJson.status&&responseJson.status != '200') {
// Alert.alert('提示',`网络错误,错误原因${responseJson.status}`)
// return
// }
// console.log(responseJson);
// this.setState({
// visible: false,
// canLogin: true,
// })
// switch (responseJson.resultCode) {
// case 0:
// // 设置推送别名
// JPushModule.setAlias('paike',()=>{},()=>{})
// JPushModule.setTags([this.username],()=>{},()=>{})
// // 登陆成功以后 储存用户信息
// storage.save({
// key: 'userInfo', //注意:请不要在key中使用_下划线符号!
// id: '1001',
// rawData: {
// username: this.username,
// password: this.password,
// token: DeviceInfo.getUniqueID(),
// },
// // 如果不指定过期时间,则会使用defaultExpires参数
// // 如果设为null,则永不过期
// expires: null,
// });
// const {navigator} = this.props;
// if (navigator) {
// navigator.replace({
// name: 'Main',
// params: {
// // token: DeviceInfo.getUniqueID(),
// username: this.username,
// password: this.password,
// // userInfo: responseJson.data.list[0],
// }
// })
// }
// break;
// case 2:
// Alert.alert('提示','登陆失败,用户名不存在!')
// break;
// case 1:
// Alert.alert('提示','登陆失败,用户名或密码错误!')
// break;
// default:
// Alert.alert('提示','登陆失败,未知错误!')
// }
// },(timeOut)=>{
// loading = false
// // alert(timeOut)
// Alert.alert('提示',timeOut,[
// {text: '确定', onPress: () => {}},
// ]);
// },'POST',body) }
} login() {
if (!this.username) {
Alert.alert('提示','请输入用户名');
return;
}
if (!this.password) {
Alert.alert('提示','请输入密码');
return;
}
if (this.state.canLogin) {
const {navigator} = this.props;
//这段代码用于判断是否用输入用户密码来登录
this.setState({
visible: true,
canLogin: false,
})
var token = DeviceInfo.getUniqueID(); var params = `userName/${this.username}/password/${this.password}`
console.log(Login_Url+params);
this.fetchDataWithURl(Login_Url+params);
}
} } const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#f5f9ff',
opacity: 1,
},
loginView: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
//backgroundColor: '#f5f9ff',
//backgroundColor: 'red',
},
logoView: {
width: width / 1.5,
height: height / 7,
justifyContent: 'center',
alignItems: 'center',
// backgroundColor: 'red',
},
logo: {
marginBottom: height/6.5,
},
inputView: {
flexDirection: 'row',
borderBottomColor: 'lightgray',
borderBottomWidth: 1,
marginLeft: 30,
marginRight: 30,
marginTop: 10,
backgroundColor: '#FFFFFF',
shadowColor: '#ccc',
shadowOffset: {width: 1, height: 1},
shadowOpacity: 0.5,
shadowRadius: 1,
//justifyContent: 'center',
alignItems: 'center', },
icon: {
width: 20,
height: 20,
justifyContent: 'center',
marginLeft: 10, },
button: {
width: width/1.2,
alignItems: 'center',
justifyContent: 'center',
height: 41,
marginLeft: 30,
marginRight: 30,
marginTop: 20,
paddingLeft:30,
paddingRight:30,
backgroundColor: '#529EF3',
borderRadius: 3,
},
spinner: {
marginBottom: 50,
position: 'absolute',
top: height / 15,
left: width / 2 - 501, },
}); module.exports = LoginNew;

Android选项最多支持3个, 多余的直接忽略不会报错, IOS可以支持多个。style:’cancel’ 的选项再最后显示, 该样式对Android无效, Android第一个选项空间比较大。

https://blog.csdn.net/yulianlin/article/details/52129726

从零学React Native之04自定义对话框的更多相关文章

  1. 从零学React Native之13 持久化存储

    数据持久化就是指应用程序将某些数据存储在手机存储空间中. 借助native存储 这种方式不言而喻,就是把内容传递给native层,通过原生API存储,详见从零学React Native之05混合开发 ...

  2. 从零学React Native之11 TextInput

    TextInput 组件是用来通过键盘输入文字,可以使用View组件和Text组件样式,没有自己特定的样式. 与Text组件类似,TextInput组件内部的元素不再使用FlexBox布局,而采用文本 ...

  3. 从零学React Native之03页面导航

    之前我们介绍了RN相关的知识: 是时候了解React Native了 从零学React Native之01创建第一个程序 从零学React Native之02状态机 本篇主要介绍页面导航 上一篇文章给 ...

  4. 从零学React Native之02状态机

    本篇文章首发于简书 欢迎关注 之前我们介绍了RN相关的知识: 是时候了解React Native了 从零学React Native之01创建第一个程序 本篇文章主要介绍下下面的知识: 1.简单界面的搭 ...

  5. 从零学React Native之10Text

    在React Native开发中,所有需要显示的字符串文本都需要放置在Text或者Text的子组件中.虽然在之前的文章中多次使用了Text组件,但是Text组件还是值得专门学习的, 并没有想象中的那么 ...

  6. 从零学React Native之08Image组件

    开发过程中, 几乎每个项目都会用到图片. RN就是通过Image组件显示图片.既可以加载网络图片,也可以加载本地资源图片. Image组件必须在样式中声明图片的款和高.如果没有声明,则图片将不会被呈现 ...

  7. 从零学React Native之05混合开发

    本篇文章,我们主要讨论如何实现Android平台的混合开发. RN给Android端发送消息 首先打开Android Studio, Open工程, 在React Native项目目录下选择andro ...

  8. 从零学React Native之14 网络请求

    通过HTTP或者HTTPS协议与网络侧服务器交换数据是移动应用中常见的通信方式. node-fetch是RN推荐的请求方式. React Native框架在初始化项目时, 引入了node-fetch包 ...

  9. 从零学React Native之12 组件的生命周期

    一个React Native组件从它被加载,到最终被卸载会经历一个完整的生命周期.所谓生命周期,就是一个对象从开始生成到最后消亡所经历的状态,理解生命周期,是合理开发的关键. ES6语法和之前的ES5 ...

随机推荐

  1. C# .net 使用正则表达式去掉字符串中的数字

    /// <summary>/// 去掉字符串中的数字/// </summary>/// <param name="key"></param ...

  2. python并发学习总结

    目录 一.理解操作系统 二.任务类型 三.Socket模块 四.一个简单的C/S程序 五.使用阻塞IO实现并发 方案一:阻塞IO+多进程 方案二:阻塞IO+多线程 阻塞IO模型的思考和总结 六.使用非 ...

  3. 如何快速将文本中的tab更换成逗号(图文详解)

    不多说,直接上干货! 现有一份数据如下. 下载日志数据并分析 到搜狗实验室下载用户查询日志 1) 介绍 搜索引擎查询日志库设计为包括约1个月(2008年6月)Sogou搜索引擎部分网页查询需求及用户点 ...

  4. Office 的下载、安装和激活(图文详细)

    不多说,直接上干货! 在这里,推荐一个很好的网址,http://www.itellyou.cn/ 销售渠道不同,激活通道也不同.有零售版,有大客户版.零售的用零售密钥激活,一对一. SW开头或在中间有 ...

  5. python-广播

    #!/usr/bin/python #coding=utf-8 #广播端 import sys,socket import time s=socket.socket(socket.AF_INET,so ...

  6. WPF Binding(四种模式)

    在使用Binding类的时候有4中绑定模式可以选择 BindingMode TwoWay 导致对源属性或目标属性的更改可自动更新对方.此绑定类型适用于可编辑窗体或其他完全交互式 UI 方案. OneW ...

  7. mysql时间统计,查询月份,周数据

    在mysql数据库中,常常会遇到统计当天的内容.例如,在user表中,日期字段为:log_time 统计当天 sql语句为: select * from user where date(log_tim ...

  8. Scrum 冲刺博客第七篇

    一.当天站立式会议照片一张 二.每个人的工作 (有work item 的ID),并将其记录在码云项目管理中 昨天已完成的工作 对排行榜的界面和功能进行初步设计 今天计划完成的工作 重新对界面进行美化 ...

  9. [PY3]——内置数据结构(3)——字符串及其常用操作

    字符串及其常用操作xmind图 字符串的定义 1. 单引号/双引号 In [1]: s1='hello world' In [2]: s1="hello world" 2. 三对单 ...

  10. Mysql工作流程分析

    Mysql工作流程图 工作流程分析 1. 所有的用户连接请求都先发往连接管理器 2. 连接管理器    (1)一直处于侦听状态    (2)用于侦听用户请求 3. 线程管理器    (1)因为每个用户 ...