Atividade 23: Projeto Calculadora
O Rito de Passagem de todo programador! Grid Visual do Teclado e Manipulação da String do Display via State.
🎯 O que vamos construir
-
✓
Usar Flexbox para alinhar fileiras de Botões (
flexDirection: 'row') -
✓
Entender o Mágico e Perigoso método
eval()do JS -
✓
Passar Parâmetros Literais pela chamada do Touch:
onPress={() => apertarBotao('7')}
🧮 A Lógica de Texto da Calculadora
A tela do Display de uma Calculadora NÃO É necessariamente um `
A Tática do eval()
Quando a tela estiver com a String Gigante `10+5*2`. Baterá um desespero porque String não é número. Como resolver a conta? Existe um "Deus C++ Javascript" oculto chamado eval(). Ele engole a sua String e resolve a expressão matemática cravada nela num passe de mágica!
const contaQueTaNaTela = "10 + 5 * 2";
// Chama o interpretador universal do console:
const resultadoRealPuro = eval(contaQueTaNaTela);
console.log(resultadoRealPuro); // A mágica C++ mostra: 20
💻 App Calc 1.0
Abra seu Snack Expo. Este App tem CSS forte pra manter a Tela Escura da Calc e as fileiras Flex alinhadinhas! Cada botão engatilha uma Função Anônima com flecha Arrow que carrega uma Pedra Parâmetro Literal para o cérebro interpretador.
import React, { useState } from 'react';
import { View, Text, TouchableOpacity, StyleSheet } from 'react-native';
export default function App() {
const [display, setDisplay] = useState('');
const [resultado, setResultado] = useState('');
// 1) Cérebro que COLA o botão clicado na tela inteira
function adicionarAoDisplay(valorApertado) {
setDisplay( display + valorApertado );
}
// 2) Botão AC de Limpar Tudo (Esvazia os dois States!)
function limparTudo() {
setDisplay('');
setResultado('');
}
// 3) Botão de Igual ( = ) que roda o EVAL
function calcularIgual() {
try {
// Roda a Magia Numérica
const resposta = eval(display);
// Colamos embaixo
setResultado(resposta.toString());
} catch (err) {
// Se o usuario botar " ++ " ou lixo bugado, cai no Catch
setResultado('Erro');
}
}
return (
<View style={styles.container}>
{/* AREA DO DISPLAY VISUAL */}
<View style={styles.displayArea}>
<Text style={styles.textoDisplay}>{display || '0'}</Text>
<Text style={styles.textoResultado}>{resultado}</Text>
</View>
{/* O TECLADO: Fileiras de Row */}
<View style={styles.tecladoLayout}>
<View style={styles.linha}>
<TouchableOpacity style={[styles.btn, styles.btnLivre]} onPress={limparTudo}>
<Text style={[styles.txtBtn, {color:'#f87171'}]}>AC</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.btn} onPress={() => adicionarAoDisplay('/')}>
<Text style={[styles.txtBtn, {color:'#60a5fa'}]}>/</Text>
</TouchableOpacity>
</View>
<View style={styles.linha}>
<TouchableOpacity style={styles.btnNum} onPress={() => adicionarAoDisplay('7')}><Text style={styles.txtBtn}>7</Text></TouchableOpacity>
<TouchableOpacity style={styles.btnNum} onPress={() => adicionarAoDisplay('8')}><Text style={styles.txtBtn}>8</Text></TouchableOpacity>
<TouchableOpacity style={styles.btnNum} onPress={() => adicionarAoDisplay('9')}><Text style={styles.txtBtn}>9</Text></TouchableOpacity>
<TouchableOpacity style={styles.btn} onPress={() => adicionarAoDisplay('*')}><Text style={[styles.txtBtn, {color:'#60a5fa'}]}>X</Text></TouchableOpacity>
</View>
<View style={styles.linha}>
<TouchableOpacity style={styles.btnNum} onPress={() => adicionarAoDisplay('4')}><Text style={styles.txtBtn}>4</Text></TouchableOpacity>
<TouchableOpacity style={styles.btnNum} onPress={() => adicionarAoDisplay('5')}><Text style={styles.txtBtn}>5</Text></TouchableOpacity>
<TouchableOpacity style={styles.btnNum} onPress={() => adicionarAoDisplay('6')}><Text style={styles.txtBtn}>6</Text></TouchableOpacity>
<TouchableOpacity style={styles.btn} onPress={() => adicionarAoDisplay('-')}><Text style={[styles.txtBtn, {color:'#60a5fa'}]}>-</Text></TouchableOpacity>
</View>
<View style={styles.linha}>
<TouchableOpacity style={styles.btnNum} onPress={() => adicionarAoDisplay('1')}><Text style={styles.txtBtn}>1</Text></TouchableOpacity>
<TouchableOpacity style={styles.btnNum} onPress={() => adicionarAoDisplay('2')}><Text style={styles.txtBtn}>2</Text></TouchableOpacity>
<TouchableOpacity style={styles.btnNum} onPress={() => adicionarAoDisplay('3')}><Text style={styles.txtBtn}>3</Text></TouchableOpacity>
<TouchableOpacity style={styles.btn} onPress={() => adicionarAoDisplay('+')}><Text style={[styles.txtBtn, {color:'#60a5fa'}]}>+</Text></TouchableOpacity>
</View>
<View style={styles.linha}>
<TouchableOpacity style={[styles.btnNum, {flex: 2, alignItems: 'flex-start', paddingLeft: 30}]} onPress={() => adicionarAoDisplay('0')}><Text style={styles.txtBtn}>0</Text></TouchableOpacity>
<TouchableOpacity style={styles.btnNum} onPress={() => adicionarAoDisplay('.')}><Text style={styles.txtBtn}>.</Text></TouchableOpacity>
<TouchableOpacity style={[styles.btn, {backgroundColor: '#3b82f6'}]} onPress={calcularIgual}><Text style={styles.txtBtn}>=</Text></TouchableOpacity>
</View>
</View>
</View>
);
}
const styles = StyleSheet.create({
container: { flex: 1, backgroundColor: '#0f172a' },
displayArea: { flex: 1, backgroundColor: '#1e293b', justifyContent: 'flex-end', padding: 25 },
textoDisplay: { color: '#94a3b8', fontSize: 30, textAlign: 'right' },
textoResultado: { color: 'white', fontSize: 50, fontWeight: 'bold', textAlign: 'right', marginTop: 10 },
tecladoLayout: { paddingBottom: 30 },
linha: { flexDirection: 'row', justifyContent: 'space-between', marginBottom: 15, paddingHorizontal: 15 },
btn: { flex: 1, backgroundColor: '#334155', aspectRatio: 1, borderRadius: 50, alignItems: 'center', justifyContent: 'center', marginHorizontal: 5 },
btnNum: { flex: 1, backgroundColor: '#1e293b', aspectRatio: 1, borderRadius: 50, alignItems: 'center', justifyContent: 'center', marginHorizontal: 5 },
btnLivre: { flex: 3 }, // O botão AC se estica pegando 3 casas!
txtBtn: { color: 'white', fontSize: 26, fontWeight: '500' }
});