React Native自定义组件——弹出框

这里用到的其实是一个新的场景页面 而不是像原生的组件一样 悬浮在页面之上,它实现的原理是从新绘制一个带弹出框样式的页面,除了弹出框之外都是灰色的,且将要显示弹出框页面的布局完全移植过来。

这里通过 BackAndroid API 实现了点击返回键 自定义对话框消失的效果

BackAndroid API 的工作机制是,当挂接多个Listener 后,用户按下返回键时,多个Listener 都会监听到返回键按下事件,并且他们的处理函数都会被执行,执行的顺序是天津的顺序,这些处理函数都执行后,只要有一个处理函数返回了true(表示返回键被按下事件已经被处理),返回键被按下事件就不会交个Android框架处理,也就是说,应用程序没有 办法退出。

程序的入口文件  index.android.js

import React, {Component} from 'react';
import {AppRegistry,Navigator,BackAndroid,Alert} from 'react-native';

import RegisterLeaft from './RegisterLeaft';
import WaitingLeaft  from './WaitingLeaft';

export default class NavigatorModule extends Component {
  
  constructor (props) {
    super(props)
    this.handleBack = this._handleBack.bind(this) // 返回一个绑定好this的方法并存储于当前实例中
  }
  
  configureScene(router){
    return Navigator.SceneConfigs.FadeAndroid;
  }
   
   renderScene(router,navigator){
    switch(router.name) {
   	case  "register":
   		return <RegisterLeaft navigator={navigator}/>
   	case  "waiting" :
   		return <WaitingLeaft 
             phoneNumber = {router.phoneNumber}
   		       userPW = {router.userPW}  
             navigator={navigator}
   		/>
   }
  }
 componentDidMount() {
     BackAndroid.addEventListener("NoviModuleListener",this.handleBack);
   }

  _handleBack () {
    const nav=this.navigator;
    if(nav!=null){
      const routers=nav.getCurrentRoutes();    
      if(routers.length>1){
      nav.pop();
      return true;
     }
    }
    return false;
  }

   componentWillUnount(){
     BackAndroid.removeEventListener("NoviModuleListener",this.handleBack);
   }

   render(){
     return(
      <Navigator
       ref={nav => {this.navigator=nav}}
       initialRoute={{name:'register'}}
       configureScene={this.configureScene}
       renderScene ={(route,navigator) =>this.renderScene(route,navigator)}
      />
     );
  }
}
   
AppRegistry.registerComponent('AwesomeProject', () => NavigatorModule);
对话框组件 ConfirmDialog.js

import React, {Component} from 'react';
import {AppRegistry,View,Text,StyleSheet,BackAndroid,Alert} from 'react-native';

let Dimensions = require('Dimensions');
let totalWidth = Dimensions.get('window').width;
let totalHeight = Dimensions.get('window').height;

export default class ConfirmDialog extends Component{

 constructor (props) {
    super(props)
    this.newHandleBack = this._newHandleBack.bind(this) // 返回一个绑定好this的方法并存储于当前实例中
  }
    render(){
        return(
            <View style={styles.ConfirmContent}>
                <View style={styles.dialogStyle}>
                   <Text style={styles.textPrompt}>
                   {this.props.promptToUser}
                   </Text>
                   <Text style={styles.yesButton}
                    onPress = {()=>{this.props.userConfirmed()}}
                    >
                    {'\r\n'}确定
                   </Text>
                   <Text style={styles.cancelButton}
                    onPress = {()=>{this.props.userCanceled()}}
                    >
                    {'\r\n'}取消
                   </Text>
                </View>
            </View>
        );
    }

    componentDidMount() {
        let amIStillAlive = this.props.amIStillAlive;
        let navigator =this.props.navigator;
        BackAndroid.addEventListener("ConfirmDialogListener",this.newHandleBack);
    }
    componentWillUnmount(){
       BackAndroid.removeEventListener("ConfirmDialogListener",this.newHandleBack);
    }

    _newHandleBack () {
        let amIStillAlive = this.props.amIStillAlive();
        let navigator =this.props.navigator;
       if(amIStillAlive==true){
              this.props.userCanceled();
              return true;
         }
          return false;
     }
}

let styles = StyleSheet.create({
    ConfirmContent:{
      position:"absolute",
      top:0,
      width:totalWidth,
      height:totalHeight,
      backgroundColor:'rgba(52,52,52,0.5)'
    },
    dialogStyle:{
      position:"absolute",
      top:totalHeight * 0.4,
      left:totalWidth / 10,
      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.1,
        backgroundColor:'gray',
        fontSize:20,
        color:'white',
        textAlign:'center'
    },
    cancelButton:{
        position:'absolute',
        bottom:10,
        right:10,
        width:totalWidth*0.35,
        height:totalHeight*0.1,
        backgroundColor:'gray',
        fontSize:20,
        color:'white',
        textAlign:'center'
    }
}
);
注册页面 RegisterLeaft.js 

import React, {Component} from 'react';
import {AppRegistry,StyleSheet, Text, View, TextInput,Alert,Navigator} from 'react-native';

import ConfirmDialog  from './ConfirmDialog';
let Dimensions = require('Dimensions');
let totalWidth = Dimensions.get('window').width;
let leftStartPoint = totalWidth * 0.1;
let componentWidth = totalWidth * 0.8;

export default class RegisterLeaft  extends Component {

 constructor(props) {
    super(props);
    this.state={
     inputedNum:"",
     inputedPW:"",
     needToConfirm:false
    };
 }

  render() {
        if(this.state.needToConfirm==true) 
        return this.renderWithDialog();
        return ( 
         	<View style = {styles.container} > 
         	<TextInput style = {styles.numberInputStyle}
            placeholder = {'请输入手机号:'} 
            onChangeText={(inputedNum)=>this.setState({inputedNum})}
            />
            <Text style = {styles.textPromptStyle} >
            您输入的手机号:{this.state.inputedNum}
            </Text >
            <TextInput style = {styles.passwordInputStyle}
            placeholder = { '请输入密码' }
            onChangeText={(inputedPW)=>this.setState({inputedPW})}
            password = 'true'
            /> 
            <Text style = {styles.bigTextPrompt}
              onPress = {()=>{this.userPressConfirm()}}
            >
            确定
            </Text> 
            </View>);
        } 
        
        renderWithDialog(){
            return ( 
         	<View style = {styles.container} > 
         	<TextInput style = {styles.numberInputStyle}
            placeholder = {'请输入手机号:'} 
            onChangeText={(inputedNum)=>this.setState({inputedNum})}
            />
            <Text style = {styles.textPromptStyle} >
            您输入的手机号:{this.state.inputedNum}
            </Text >
            <TextInput style = {styles.passwordInputStyle}
            placeholder = {'请输入密码'}
            onChangeText={(inputedPW)=>this.setState({inputedPW})}
            password = 'true'
            /> 
            <Text style = {styles.bigTextPrompt}
              onPress ={()=>{this.userPressConfirm()}}
            >
            确定
            </Text> 
            <ConfirmDialog
             userConfirmed={()=>{this.userConfirmed()}}
             userCanceled = {()=>{this.userCanceled()}}
             amIStillAlive= {()=>{this.tellConfirmDialogItsStatus()}}
             promptToUser ={'使用'+this.state.inputedNum+'号码登录?'}
            >
            </ConfirmDialog>
            </View>);
        }
       
    userPressConfirm(){
        this.setState({needToConfirm:true});
        
    }
    userCanceled(){
        this.setState({needToConfirm:false});
    }
    userConfirmed(){
        this.setState({needToConfirm:true});
        this.props.navigator.push({
            phoneNmuber:this.state.inputedNum,
            userPW:this.state.inputedPW,
            name:"waiting"
        });
    }

   tellConfirmDialogItsStatus(){
        return this.state.needToConfirm;
    }

        
  }

let styles = StyleSheet.create({
    container: {
        flex: 1,
        backgroundColor: 'white'
    },
    numberInputStyle: {
        top: 20,
        left: leftStartPoint,
        width: componentWidth,
        backgroundColor: 'gray',
        fontSize: 20

    },
    textPromptStyle: {
        top: 30,
        left: leftStartPoint,
        width: componentWidth,
        fontSize: 20
    },
    passwordInputStyle: {
        top: 50,
        left: leftStartPoint,
        width: componentWidth,
        backgroundColor: 'gray',
        fontSize: 20
    },
    bigTextPrompt: {
        top: 70,
        left: leftStartPoint,
        width: componentWidth,
        backgroundColor: 'gray',
        color: 'white',
        textAlign: 'center',
        fontSize: 40
    }
});

等待页面 WaitingLeaft.js

import React, {Component} from 'react';
import {AppRegistry, StyleSheet, Text, View, TextInput} from 'react-native';

export default class WaitingLeaft extends Component{

    render() {
         return ( 
         	<View style = {styles.container} > 
            <Text style = {styles.textPromptStyle} >
             注册使用手机号码:{this.props.phoneNumber} 
            </Text >
            <Text style = {styles.textPromptStyle} >
            注册使用密码:{this.props.userPW} 
            </Text >
            <Text style = {styles.bigTextPrompt}
             onPress = {this.goBack.bind(this)}
            >
             返回
            </Text> 
            </View>);
        }

        goBack(){
           this.props.navigator.push(
                {
                    name:"register"
                }
            );
        }
  }

let styles = StyleSheet.create({
    container: {
        flex: 1,
        justifyContent:'center',
        alignItems:'center',
        backgroundColor:'#F5FCFF'
    },
    textPromptStyle: {
        fontSize: 20

    },
    bigTextPrompt: {
        width: 300,
        backgroundColor: 'gray',
        color: 'white',
        textAlign: 'center',
        fontSize: 60
    }
});



代码 链接: https://pan.baidu.com/s/1c2EHTD2 密码: hy7b






  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
React Native中的自定义控件使用与React相同的组件方式进行实现。以下是自定义控件的基本步骤: 1. 创建一个自定义控件组件:在你的项目中创建一个新的组件,该组件包含你自定义的UI元素。 2. 定义控件属性:你可以在组件的props中定义一些属性,这些属性可以用来设置控件的外观和行为。 3. 实现控件逻辑:在组件的render方法中实现控件的逻辑,包括控件的事件处理、状态管理等。 4. 导控件:将你的自定义控件组件,以便其他组件可以使用它。 以下是一个简单的例子,演示如何创建自定义控件: ``` import React, { Component } from 'react'; import { Text, TouchableOpacity } from 'react-native'; class CustomButton extends Component { constructor(props) { super(props); this.state = { pressed: false, }; } handlePress = () => { this.setState({ pressed: true }); }; handleRelease = () => { this.setState({ pressed: false }); }; render() { const { title, disabled } = this.props; const { pressed } = this.state; const buttonStyle = [ styles.button, disabled && styles.disabled, pressed && styles.pressed, ]; return ( <TouchableOpacity style={buttonStyle} onPress={this.handlePress} onPressOut={this.handleRelease} activeOpacity={0.6} disabled={disabled} > <Text style={styles.text}>{title}</Text> </TouchableOpacity> ); } } const styles = { button: { backgroundColor: '#007aff', paddingVertical: 10, paddingHorizontal: 20, borderRadius: 5, }, disabled: { opacity: 0.5, }, pressed: { backgroundColor: '#0051a8', }, text: { color: '#fff', fontSize: 16, fontWeight: 'bold', textAlign: 'center', }, }; export default CustomButton; ``` 在上面的例子中,我们创建了一个CustomButton组件,它包含一个TouchableOpacity,以及一些属性和状态来控制按钮的外观和行为。在render方法中,我们使用了一些简单的样式来设置按钮的外观,以及一些事件处理来处理按钮的行为。最后,我们将CustomButton组件,以便其他组件可以使用它。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值