本篇主要介绍: 
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. header请求头信息详细介绍

    https://www.byvoid.com/zhs/blog/http-keep-alive-header HTTP协议头部与Keep-Alive模式详解 1.什么是Keep-Alive模式? 我们 ...

  2. Java中的语法树结构

    1.JCTypeParameter class B<T extends CA&IA&IB> { ...} 截图如下: 接口继承了StatementTree接口,而实现类实现 ...

  3. DOS命令行操作MySQL数据库中文乱码问题解决

    我们在 dos 命令行操作中文时,会报错 ’); ERROR (HY000): Incorrect string value: '\xD5\xC5\xC8\xFD' for column 原因:因为 ...

  4. JavaScript数据结构-8.双向链表

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  5. Ubuntu 安装 Caffe

    Caffe Caffe 安装(Python2 CPU版本) 参考博文https://blog.csdn.net/pangyunsheng/article/details/79418896 安装环境 U ...

  6. 把AspDotNetCoreMvc程序运行在Docker上-part2:修改容器以及发布镜像

    在上一个part<把AspDotNetCoreMvc程序运行在Docker上-part1>,已经将成功将aspdotnetcore程序运行在两个不同的容器中,目前两个容器的内容完全相同,只 ...

  7. POJ 3710:Matrix Power Series

    Description 给出矩阵 \(n*n\) 的 矩阵\(A\) , 求 \(A^1+A^2+A^3...+A^k\) Solution 首先我们设 \(S_n=\sum_{i=1}^{n}A^i ...

  8. 应输入 #endregion 指令报错的排查技巧

    VS2010中错误排查的一个小技巧,欢迎大家吐槽: 错误    9    应输入 #endregion 指令sses.cs    3778    2  xxx.xx   这个错很明显,是缺少#endr ...

  9. 在Ubuntu16.04.4和Windows10上安装jdk

    在Ubuntu16.04.4和Windows10上安装jdk 一.在Ubuntu16.04.4上安装jdk  1.下载jdk安装包     首先我们在oracle官网上下载jdk-8u161-linu ...

  10. 题解 P1068 【分数线划定】

    由于涉及到排序和对应序号 那就定义一个结构体 结合STL模板中的sort日常沉迷sort 提示:虽然我也是蒟弱 sort是快速排序函数,有两个或三个参数, 两个参数适用于平常的数字类型,即形sort( ...