irpas技术客

react native的Modal组件的坑 自定义弹框_小楼昨夜春_react native modal 键盘弹框

网络投稿 4907

最近做react native 项目发现自带的Modal组件引起了很多的坑导致项目里的弹框最终都重新实现;

?

Modal组件引起的问题:

1.Modal组件导致很多全局的监听失效比如键盘的监听和前后台的监听;

2.android目前主要是监听的失效,在ios里就是各种问题,无法同时出现2个Modal和在Modal页面跳转到其他app的会报错

3.eg

?

问题分析:官网说modal组件使用原生实现防止卡顿,可能就是这种原生实现,独立于当前页面导致的各种奇葩问题。

?

项目有2中方案解决这个问题,

1. 通过Position自定义一个全局的悬浮View模仿弹框效果,但这种会导致手势操作的时候无法操作弹框。

2.因为组件是使用的React-native-Navigation组件,Navigation可以设置Screeen透明显示,从而实现蒙版效果,这样就不会存在各种问题,和当前页面完美融合, 也不会存在手势的问题,很方便的监听返回手势;

?

具体代码:

在Navigation组件下面定义蒙版AlertDialog页面;

?

<Stack.Screen options={{ headerShown: false, cardStyle: { backgroundColor: 'rgba(255,255,255, 0)' }, cardOverlayEnabled: true, cardStyleInterpolator: ({ current: { progress } }) => ({ cardStyle: { opacity: progress.interpolate({ inputRange: [0, 0.5, 0.9, 1], outputRange: [0, 0.25, 0.7, 1], }) }, overlayStyle: { opacity: progress.interpolate({ inputRange: [0, 1], outputRange: [0, 0.2],// 设置透明度 extrapolate: 'clamp' }) } }) }} name="AlertDialog" component={AlertDialogScreen}

定义alertDialog.js

import { COLORS } from '../../constants/Colors'; import React, { useEffect, useState } from 'react'; import { View, Text, StyleSheet, Keyboard, TouchableWithoutFeedback, Platform, TouchableOpacity } from 'react-native'; import * as RootNavigation from '../../navigation/RootNavigation'; /** * 弹框基础类 支持自定义内容,RN自带的Modal导致很多问题,通过Nvigateion 提供的modal方法定义弹框 * @param {*} props * @returns */ export default function AppVersionDialogScreen(props) { const { route } = props; // 通过拉Nvigateion route 传递自定义内容 const { title, contenComponent, footButton, callBack, footCallBack, buttonLeftText, buttonRightText, buttonType } = route.params; console.log('dialog alert back', buttonType); const getFootView = () => { let footView = <View></View>; switch (buttonType) { case 'custom': footView = <View style={styles.footContainer}> <View style={{ width: '40%' }}> {buttonLeftText && <TouchableOpacity style={styles.button} onPress={footCallBack.buttonLeftCallBack || (() => { RootNavigation.goBack() })} > <Text style={styles.buttonText}> {buttonLeftText} </Text> </TouchableOpacity>} </View> <View style={{ width: '40%' }}> {buttonRightText && <TouchableOpacity style={styles.button} onPress={footCallBack.buttonRightCallBack || (() => { RootNavigation.goBack() })} > <Text style={styles.buttonText}>{buttonRightText}</Text> </TouchableOpacity>} </View> </View> break; default: footView = !!footButton ? footButton(footCallBack) : ( <TouchableOpacity style={styles.button} onPress={() => { RootNavigation.goBack(); }}> <Text style={styles.buttonText}>CLOSE</Text> </TouchableOpacity>); break; } return footView; } const footView = getFootView(); return ( <TouchableWithoutFeedback onPress={() => { // RootNavigation.goBack();; }} > <View style={styles.container}> <View style={styles.toastContainer}> <View style={styles.titleContainer}> <Text style={styles.title}>{title}</Text> </View> <View style={styles.contentContainer}> { contenComponent(callBack) } </View> <View style={styles.bottomContainer}> { footView } </View> </View> </View> </TouchableWithoutFeedback> ); } const styles = StyleSheet.create({ container: { width: '100%', height: '100%', justifyContent: 'center', alignItems: 'center', }, toastContainer: { width: '90%', // height: 250, backgroundColor: COLORS.WHITE, borderRadius: 10 }, titleContainer: { width: '100%', justifyContent: 'center', }, contentContainer: { width: '100%', marginTop: 10, justifyContent: 'center', alignItems: 'center' }, footContainer: { justifyContent: 'space-between', alignSelf: 'center', width: '90%', flexDirection: 'row', marginBottom: 10 }, // topContainer: { // justifyContent: 'center', // }, title: { marginTop: 10, marginBottom: 10, marginLeft: '5%', fontFamily: 'alibaba-sans', fontSize: 14, color: COLORS.STANDARD_GRAY, fontWeight: 'bold' }, contentText: { marginLeft: '5%', fontFamily: 'alibaba-sans', fontSize: 17, color: COLORS.STANDARD_GRAY }, bottomContainer: { width: '100%', alignSelf: 'flex-end', // height: 40, justifyContent: 'center', alignItems: 'center', marginBottom: 20, marginTop: 40 }, button: { width: '90%', alignItems: 'center' }, buttonText: { fontFamily: 'alibaba-sans', fontSize: 14, fontWeight: 'bold', color: COLORS.STANDARD_GRAY } });

通过这个组件完美可以自定义内容和底部的按钮

?

使用方法:

const getAlertDialogData = () => { const contenComponent = () => <View style={styles.contenContainer}> <Text style={styles.textContent}> The distribution network failed to re-bind or return to the home page </Text> </View> const data = { contenComponent, title: 'network error', buttonType: 'custom', buttonLeftText: 'Rebind', buttonRightText: 'Back Home', footCallBack: { buttonLeftCallBack: () => { RootNavigation.navigate('DeviceTypeSelect') }, buttonRightCallBack: () => { RootNavigation.navigate('Home') } } }; return data; } DialogUtil.createAlertDialog('AlertDialog', getAlertDialogData());

?

DialogUtil.js

import * as RootNavigation from '../navigation/RootNavigation'; export default class DialogUtil { static createAlertDialog(dialogName, data) { RootNavigation.navigate(dialogName, data); } }

?

这样就实现了一个弹框效果如下

?

?


1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,会注明原创字样,如未注明都非原创,如有侵权请联系删除!;3.作者投稿可能会经我们编辑修改或补充;4.本站不提供任何储存功能只提供收集或者投稿人的网盘链接。

标签: #React #Native #modal #键盘弹框 #最近做react #项目有2中方案解决这