As caixas de alerta são um componente intrínseco da web e sua utilidade varia de acordo com seus casos de uso. Eles são usados para exibir mensagens, avisos, alertas e consentimentos de confirmação.
Com uma caixa de diálogo de alerta, o usuário geralmente obtém as opções de botão para concordar, discordar e cancelar. Às vezes, os alertas também são usados para registrar a entrada de um usuário, mas isso depende da plataforma.
Neste artigo, aprenderemos como criar uma caixa de diálogo de alerta personalizado no React Native para atender às necessidades do seu projeto.
Introdução
O React Native fornece uma API de alerta, que pode ser usada para exibir caixas de diálogo de alerta nativas no Android e iOS. Mas há limitações com as caixas de diálogo de alerta nativas.
Por exemplo, no Android não podemos mostrar mais do que três botões e nenhuma opção é fornecida para capturar as entradas dos usuários. Embora o iOS permita que tenhamos muitos botões e que os usuários insiram os dados, ainda não podemos mostrar imagens, gráficos ou ter qualquer tipo de personalização, exceto texto.
Para lidar com essas limitações, precisamos crie diálogos de alerta personalizados. Uma caixa de diálogo de alerta personalizado pode atuar como modal e oferecer suporte a componentes.
Propriedades de uma caixa de alerta
Antes de personalizar qualquer componente nativo, devemos ter um entendimento claro de sua arquitetura e tratamento de eventos.
Por exemplo, um botão contém várias propriedades, como rótulo e bulginess. Um botão também mantém eventos como pressionar, segurar, soltar, pairar e assim por diante. Quando o personalizamos, precisamos considerar todas essas propriedades. Caso contrário, perderemos a aparência, o comportamento e a funcionalidade.
Uma caixa de alerta nativa tem as seguintes propriedades:
Título-Um título de texto para indicar a finalidade do Alerta. Compatível com Android e iOS Mensagem-Uma mensagem de texto para explicar o aviso ou aviso. Compatível com botões Android e iOS-Android suporta um máximo de três botões, enquanto iOS suporta toque externo ilimitado-Alerta no Android pode ser fechado tocando fora do alerta onPress-Função para chamar com o pressionar de um botão. Tanto o Android quanto o iOS suportam onDismiss-Função para chamar quando um alerta é fechado. Apenas o Android suporta este Prompt-Permite que os usuários insiram dados nos campos de entrada. Apenas iOS suporta este botão Voltar-Por padrão, o Alerta fecha com o pressionamento de um botão Voltar no Android
Precisamos considerar todas essas propriedades ao personalizar a caixa de Alerta.
A IU e a arquitetura do caixas de diálogo de alerta
Vamos ver a aparência do Alerta nativo e a colocação de diferentes elementos nele. Os alertas do Android e do iOS são diferentes na aparência:
Especificações do Android
De acordo com Material conceitos de design , a tipografia e as cores das caixas de diálogo de alerta do Android são as seguintes:
Outras propriedades como altura, largura, preenchimento, margem, etc. são as seguintes:
Para pequeno ações do botão:
Fonte: material.io
Para ações de botões longos:
Fonte: material.io
Outras propriedades incluem:
Elevação-24 dp
Posição-centro
Margem mínima dos lados-48dp
Especificações do iOS
Da mesma forma, para iOS, temos as seguintes especificações:
Esta informação é coletada em Ionic Documentação do AlertController.
Bibliotecas e pacotes de alertas personalizados
Existem algumas bibliotecas no GitHub que permitem criar caixas de alerta personalizadas. Alguns deles são react-native-awesome-alerts, react-native-dialog e react-native-modal. Você pode experimentar essas bibliotecas, mas, neste artigo, iremos personalizar a caixa de alerta sem elas.
A diferença entre alerta e modal
Alerta e modal são semanticamente as mesmas coisas com uma diferença em complexidade e usabilidade.
Os diálogos de alerta foram criados para exibir mensagens curtas da maneira mais simples possível e é por isso que sua funcionalidade é limitada.
Por outro lado , os modais são usados para exibições complexas. Eles exigem que definamos todo o conteúdo por nós mesmos. Por padrão, eles fornecem ouvintes de eventos como um manipulador de botão Voltar.
Personalizando a caixa de diálogo de alerta
Vamos primeiro verificar o que iremos personalizar. Devemos lembrar que os alertas são usados para exibir mensagens importantes. Podem ser erros, avisos ou notificações. Eles não se destinam a mostrar imagens ou preencher formulários. Para isso, você deve usar modais.
Em Alerta, iremos personalizar:
A cor de fundo da caixa de diálogo A cor da fonte, tamanho, peso, etc. do título e da mensagem A cor da fonte , cor de fundo e estilo de borda dos botões
Como o React Native chama os componentes nativos de alerta do Android e iOS, ele não fornece um método direto para personalizá-los. Alertas são componentes fixos com finalidade definida e, portanto, não personalizáveis no Android e iOS. Os desenvolvedores Android usam a classe Dialog para isso.
Em nosso caso, vamos usar a API Modal do React Native. As vantagens de usar esta API são:
Não precisamos nos preocupar com a colocação de nosso Alerta personalizado. Ele permanecerá na parte superior de todo o aplicativo. O evento do botão Voltar no Android e o botão de menu na Apple TV serão automaticamente tratados por ele
Breve introdução ao React Native Modal
A API React Native Modal fornece um contêiner que é exibido acima de sua visão envolvente. Uma propriedade booleana visível é passada ao componente modal para mostrá-la ou ocultá-la. Existem outros adereços, mas não estamos preocupados com eles porque não são úteis para um Alerta.
É assim que o Modal funciona:
import React, {useState} from’reagir’; import {modal, texto, prensável, visualização} de’react-native’; const App=()=> {const [modalVisible, setModalVisible]=useState (false); return (
modalVisible é a variável de estado usada para mostrar ou ocultar o Modal. Você pode manter o modal em uma única página ou incluir todo o seu aplicativo em sua Visualização pai. É melhor usar uma biblioteca de gerenciamento de armazenamento e estado como o Redux porque ela ajudará você a alterar a variável modalVisible de qualquer lugar em um aplicativo.
Criando um botão para abrir o Alerta
Primeiro de tudo, precisaremos de um evento para alterar o valor de modalVisible. Em nosso código, usaremos um botão. Ao pressionar este botão, modalVisible se tornará verdadeiro e um Modal será exibido. Para criar o botão, usaremos o componente Pressable:
import React, {useState} from’react’; import {modal, texto, prensável, visualização} de’react-native’; const App=()=> {const [modalVisible, setModalVisible]=useState (false); return (
Neste código, adicionamos alguns estilos para melhorar a aparência do botão e outras partes do aplicativo. Atualmente, ele mostrará um botão. Tocar neste botão abrirá o modal. A saída renderizada será semelhante a:
Criando a IU da caixa de diálogo de alerta
A próxima etapa é criar a IU modal. Mas, primeiro, precisamos definir uma maneira de diferenciar entre a IU padrão de ambos os sistemas operacionais. O iOS tem uma visão diferente do Android. Para reconhecer o sistema operacional, o React Native fornece a API da plataforma.
Vamos começar criando o pano de fundo. Conforme discutimos na seção IU e arquitetura, a cor de fundo e a opacidade no Android são # 232F34 e 0,32, respectivamente. Para iOS, esses valores são # 000000 e 0,3 respectivamente:
import React, {useState} from’react’; import {Modal, Texto, Pressionável, Visualização, Plataforma} de’react-nativo’; const App=()=> {const [modalVisible, setModalVisible]=useState (false); return (
A saída renderizada ficará assim:
Observe que usamos o componente Pressable para criar o cenário. Isso porque queríamos adicionar a funcionalidade de fechar o modal ao pressionar o pano de fundo.
Em seguida, criaremos uma caixa de diálogo de alerta sobre esse pano de fundo. Mas primeiro, devemos colocar o Modal em um componente separado. Isso ajudará a chamar nosso Alerta personalizado com estilos diferentes:
import React, {useState} de”react”; import {Alert, Modal, StyleSheet, Text, Pressable, View, Platform} de”react-native”; const CustomAlert=(props)=> {return (
Criamos um componente diferente com o nome CustomAlert e colocamos nosso Modal nele.
O estado modalVisible é mantido em App.js, mas lembre-se de que a melhor abordagem é usar um gerenciamento de armazenamento central biblioteca como Redux. Redux tornará o estado modalVisible acessível a todos os componentes em todo o aplicativo e não haverá a necessidade de passar modalVisible como adereços.
É hora de definir os valores padrão para Modal. Esses valores projetarão a caixa semelhante à caixa de alerta nativa para Android e iOS.
Já definimos todos os valores na seção de IU e arquitetura. Vamos começar com o Android.
Diálogo de alerta personalizado do Android
Os valores padrão são:
Esses valores padrão são definidos no componente CustomAlert. Eles são usados nos casos em que um usuário não fornece valores.
Diferentes props para o componente CustomAlert são:
Verifique este código para entender como CustomAlert está definindo os padrões:
const CustomAlert=(props)=> {const [androidDefaults, setAndroidDefaults]=useState ({container: {backgroundColor: (props.android && props.android.container && props.android.container.backgroundColor) ||’#FAFAFA’,}, title: {color: (props.android && props.android. title && props.android.title.color) ||’# 000000′, fontFamily: (props.android && props.android.title && props.android.title.fontFamily) ||’initial’, fontSize: (props.android && props.android.title && props.android.title.fontSize) || 22, fontWeight: (props.android && props.android.title && props.android.title.fontWeight) ||’negrito’,}, mensagem: {color: (props.android && props.android.message && props.android.message.color) ||’# 000000′, fontFamily: (props.android && props.android.message && props.android.message.fontFamily) ||’initial’, fontSize: (props.android && props.android.message && props.android.message.fontSize) || 15, fontWeight: (props.android && props.android.message && props.android.message.fontWeight) ||’normal’,}, botão: {color:’# 387ef5′, fontFamily:’initial’, fontSize: 16, fontWeight:’500′, textTransform:’uppercase’, backgroundColor:’transparent’,},}); return (
Alguns estilos são para o layout e é por isso que não oferecemos a opção de alterá-los. Eles são declarados no objeto StyleSheet:
const styles=StyleSheet.create ({centeredView: {flex: 1, justifyContent:”center”, alignItems:”center”, marginTop: 22}, botão: {borderRadius: 20 , preenchimento: 10, elevação: 2}, buttonOpen: {backgroundColor:”# F194FF”,}, textStyle: {color:”white”, fontWeight:”bold”, textAlign:”center”}, iOSBackdrop: {backgroundColor:”# 000000″, opacidade: 0,3}, androidBackdrop: {backgroundColor:”# 232f34″, opacidade: 0,4}, pano de fundo: {position:’absoluto’, top: 0, left: 0, bottom: 0, right: 0}, alertBox: {flex: 1, justifyContent:’center’, alignItems:’center’}, androidAlertBox: {maxWidth: 280, width:’100%’, margin: 48, elevation: 24, borderRadius: 2,}, androidTitle: {margin: 24,}, androidMessage: {marginLeft: 24, marginRight: 24, marginBottom: 24,}, androidBut tonGroup: {marginTop: 0, marginRight: 0, marginBottom: 8, marginLeft: 24,}, androidButton: {marginTop: 12, marginRight: 8,}, androidButtonInner: {preenchimento: 10,}});
Se executarmos isso usando configurações diferentes, obteremos os seguintes resultados:
É hora de adicionar os botões à caixa de diálogo de alerta. Existem algumas especificações do Android:
Um único botão está sempre OK Dois botões são CANCELAR e OK Três botões são PERGUNTAR MAIS TARDE, CANCELAR e OK No máximo, três botões são suportados Dois botões flutuam no lado direito da caixa enquanto o terceiro botão flutua no lado esquerdo. Os botões longos são exibidos em linhas separadas
Para cumprir todas essas condições, decidimos declarar um componente separado para um grupo de botões. Vamos chamá-lo de AndroidButtonBox. Verifique o código:
const AndroidButtonBox=()=> {const [buttonLayoutHorizontal, setButtonLayoutHorizontal]=useState (1); const buttonProps=props.buttons && props.buttons.length> 0? props.buttons: [{}] return (
Neste código, declaramos uma variável de estado, buttonLayoutHorizontal. Isso será usado para alterar o layout do grupo de botões de colunas para linhas. Se todos os botões forem curtos, eles serão exibidos em uma única linha.
O evento onLayout é usado para determinar se há necessidade de alterar esta variável de estado. Em seguida, executamos um loop sobre a matriz de botões fornecida por meio de adereços e criamos botões com estilo adequado.
O código inteiro (para Android) será semelhante a este:
import React, {useState} from”reagir”; import {Alert, Modal, StyleSheet, Text, Pressable, View, Platform} de”react-native”; const CustomAlert=(props)=> {const [androidDefaults, setAndroidDefaults]=useState ({container: {backgroundColor: (props.android && props.android.container && props.android.container.backgroundColor) ||’#FAFAFA’, }, título: {cor: (props.android && props.android.title && props.android.title.color) ||’# 000000′, fontFamily: (props.android && props.android.title && props.android. title.fontFamily) ||’inicial’, fontSize: (props.android && props.android.title && props.android.title.fontSize) || 22, fontWeight: (props.android && props.android.title && props. android.title.fontWeight) ||’bold’,}, mensagem: {color: (props.android && props.android.message && props.android.message.color) ||’# 000000′, fontFamily: (props. android && props.android.message && props.android.message.fontFamily) ||’initial’, fontSize: (props.android && props.android.message && props.android.message.fontSize) || 15, fontWeight: ( suporte s.android && props.android.message && props.android.message.fontWeight) ||’normal’,}, botão: {color:’# 387ef5′, fontFamily:’initial’, fontSize: 16, fontWeight:’500′, textTransform:’uppercase’, backgroundColor:’transparent’,},}); const AndroidButtonBox=()=> {const [buttonLayoutHorizontal, setButtonLayoutHorizontal]=useState (1); const buttonProps=props.buttons && props.buttons.length> 0? props.buttons: [{}] return (
The rendered output for different values of CustomAlert are:
iOS custom alert dialog
The code for an iOS alert box will be similar to Android with changes in styling.
In iOS, all the entities like the title, message, and buttons are center aligned. There can be any number of buttons. The complete code for an iOS and Android CustomAlert box is:
import React, { useState } from”react”; import { Alert, Modal, StyleSheet, Text, Pressable, View, Platform } from”react-native”; const CustomAlert=(props)=> { const [androidDefaults, setAndroidDefaults]=useState({ container: { backgroundColor: (props.android && props.android.container && props.android.container.backgroundColor) ||’#FAFAFA’, }, title: { color: (props.android && props.android.title && props.android.title.color) ||’#000000′, fontFamily: (props.android && props.android.title && props.android.title.fontFamily) ||’initial’, fontSize: (props.android && props.android.title && props.android.title.fontSize) || 22, fontWeight: (props.android && props.android.title && props.android.title.fontWeight) ||’bold’, }, message: { color: (props.android && props.android.message && props.android.message.color) ||’#000000′, fontFamily: (props.android && props.android.message && props.android.message.fontFamily) ||’initial’, fontSize: (props.android && props.android.message && props.android.message.fontSize) || 15, fontWeight: (prop s.android && props.android.message && props.android.message.fontWeight) ||’normal’, }, button: { color:’#387ef5′, fontFamily:’initial’, fontSize: 16, fontWeight:’500′, textTransform:’uppercase’, backgroundColor:’transparent’, }, }); const [iOSDefaults, setIOSDefaults]=useState({ container: { backgroundColor: (props.ios && props.ios.container && props.ios.container.backgroundColor) ||’#F8F8F8′, }, title: { color: (props.ios && props.ios.title && props.ios.title.color) ||’#000000′, fontFamily: (props.ios && props.ios.title && props.ios.title.fontFamily) ||’initial’, fontSize: (props.ios && props.ios.title && props.ios.title.fontSize) || 17, fontWeight: (props.ios && props.ios.title && props.ios.title.fontWeight) ||’600′, }, message: { color: (props.ios && props.ios.message && props.ios.message.color) ||’#000000′, fontFamily: (props.ios && props.ios.message && props.ios.message.fontFamily) ||’initial’, fontSize: (props.ios && props.ios.message && props.ios.message.fontSize) || 13, fontWeight: (props.ios && props.ios.message && props.ios.message.fontWeight) ||’normal’, }, button: { color:’#387ef5′, fontFamily:’init ial’, fontSize: 17, fontWeight:’500′, textTransform:’none’, backgroundColor:’transparent’, }, }); const AndroidButtonBox=()=> { const [buttonLayoutHorizontal, setButtonLayoutHorizontal]=useState(1); const buttonProps=props.buttons && props.buttons.length > 0 ? props.buttons: [{}] return (
The rendered output for different CustomAlert values are:
Live Demo
Conclusion
In this article, we learned about alert dialogs in both Android and iOS. We also saw the difference between their UI, specifications, and properties.
These alert dialogs have a defined purpose and they should not be overused. Use them only when the message is unavoidable for users, because they block the UI.
There are a lot of scope of enhancements in our custom alert. You can change the paddings, margins, add background images, icons, SVG, etc. If you try this code in your projects, then please let me know how it worked through comments. Thank you.