Módulo 5 PROJETOS

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 ``. Nós usamos uma Tag Literal `<Text>` e dentro do State a gente vai "Colando" as letras que o usuário aperta. Se ele aperta '7', nós concatenamos a string com '7'. Se clica '*', colamos o multiplicador.

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.

App.js
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' }
});

📝 Quiz - Sintaxes e Math