diff --git a/.idea/deploymentTargetSelector.xml b/.idea/deploymentTargetSelector.xml index 07b225a..e63fc71 100644 --- a/.idea/deploymentTargetSelector.xml +++ b/.idea/deploymentTargetSelector.xml @@ -2,10 +2,10 @@ - + - + diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 976fb5c..be87448 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -4,12 +4,12 @@ plugins { android { namespace = "com.example.conversordemoedas2" - compileSdk = 36 + compileSdk = 34 defaultConfig { applicationId = "com.example.conversordemoedas2" minSdk = 24 - targetSdk = 36 + targetSdk = 34 versionCode = 1 versionName = "1.0" diff --git a/app/src/main/java/com/example/conversordemoedas2/Conversion.java b/app/src/main/java/com/example/conversordemoedas2/Conversion.java index 6a6a649..2efff29 100644 --- a/app/src/main/java/com/example/conversordemoedas2/Conversion.java +++ b/app/src/main/java/com/example/conversordemoedas2/Conversion.java @@ -4,12 +4,19 @@ import java.text.SimpleDateFormat; import java.util.Date; import java.util.Locale; +// ======================= Conversor de Moedas ======================= public class Conversion { + // Identificador do registro no histórico private int id; + // Código da moeda de origem (ex.: USD) private String fromCurrency; + // Código da moeda de destino (ex.: BRL) private String toCurrency; + // Valor informado pelo usuário private double amount; + // Resultado da conversão private double result; + // Data/hora em millis desde epoch private long date; public Conversion(int id, String fromCurrency, String toCurrency, @@ -39,12 +46,14 @@ public class Conversion { public void setDate(long date) { this.date = date; } public String getFormattedDate() { + // Formata a data no padrão dd/MM/yyyy HH:mm SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy HH:mm", Locale.getDefault()); return sdf.format(new Date(date)); } @Override public String toString() { + // String amigável para debug/listagem simples return String.format("%.2f %s = %.2f %s (%s)", amount, fromCurrency, result, toCurrency, getFormattedDate()); } diff --git a/app/src/main/java/com/example/conversordemoedas2/ConversionHistoryAdapter.java b/app/src/main/java/com/example/conversordemoedas2/ConversionHistoryAdapter.java index 0b0e0cb..50354b6 100644 --- a/app/src/main/java/com/example/conversordemoedas2/ConversionHistoryAdapter.java +++ b/app/src/main/java/com/example/conversordemoedas2/ConversionHistoryAdapter.java @@ -8,9 +8,13 @@ import android.widget.BaseAdapter; import android.widget.TextView; import java.util.List; +// ======================= Conversor de Moedas ======================= public class ConversionHistoryAdapter extends BaseAdapter { + // Contexto para inflar layouts private Context context; + // Lista de conversões exibidas private List conversions; + // Inflater padrão para criar views da lista private LayoutInflater inflater; public ConversionHistoryAdapter(Context context, List conversions) { @@ -39,6 +43,7 @@ public class ConversionHistoryAdapter extends BaseAdapter { ViewHolder holder; if (convertView == null) { + // Usa layout simples com duas linhas de texto convertView = inflater.inflate(android.R.layout.simple_list_item_2, parent, false); holder = new ViewHolder(); holder.text1 = convertView.findViewById(android.R.id.text1); @@ -50,14 +55,14 @@ public class ConversionHistoryAdapter extends BaseAdapter { Conversion conversion = conversions.get(position); - // Texto principal: conversão + // Linha principal: valor convertido String mainText = String.format("%.2f %s = %.2f %s", conversion.getAmount(), conversion.getFromCurrency(), conversion.getResult(), conversion.getToCurrency()); - // Texto secundário: data + // Linha secundária: data/hora String subText = conversion.getFormattedDate(); holder.text1.setText(mainText); @@ -67,6 +72,7 @@ public class ConversionHistoryAdapter extends BaseAdapter { } public void updateData(List newConversions) { + // Atualiza a lista e notifica para redesenhar this.conversions = newConversions; notifyDataSetChanged(); } diff --git a/app/src/main/java/com/example/conversordemoedas2/Currency.java b/app/src/main/java/com/example/conversordemoedas2/Currency.java index 2a79c4e..3baa1d0 100644 --- a/app/src/main/java/com/example/conversordemoedas2/Currency.java +++ b/app/src/main/java/com/example/conversordemoedas2/Currency.java @@ -1,10 +1,16 @@ package com.example.conversordemoedas2; +// ======================= Conversor de Moedas ======================= public class Currency { + // Identificador interno no banco private int id; + // Código ISO da moeda (ex.: USD, BRL) private String code; + // Nome descritivo (ex.: Dólar Americano) private String name; + // Símbolo monetário (ex.: $, R$) private String symbol; + // Taxa relativa ao USD (quantos USD 1 unidade desta moeda vale) private double rateToUsd; public Currency(int id, String code, String name, String symbol, double rateToUsd) { @@ -31,6 +37,7 @@ public class Currency { @Override public String toString() { + // Formato exibido nos spinners (código - nome (símbolo)) return code + " - " + name + " (" + symbol + ")"; } } diff --git a/app/src/main/java/com/example/conversordemoedas2/CurrencyConverter.java b/app/src/main/java/com/example/conversordemoedas2/CurrencyConverter.java index d1bfd42..82154ed 100644 --- a/app/src/main/java/com/example/conversordemoedas2/CurrencyConverter.java +++ b/app/src/main/java/com/example/conversordemoedas2/CurrencyConverter.java @@ -3,7 +3,9 @@ package com.example.conversordemoedas2; import android.content.Context; import java.util.List; +// ======================= Conversor de Moedas ======================= public class CurrencyConverter { + // Acesso ao banco SQLite para moedas e histórico private DatabaseHelper dbHelper; public CurrencyConverter(Context context) { @@ -12,7 +14,7 @@ public class CurrencyConverter { } private void initializeDatabase() { - // Seed additional currencies if missing + // Insere moedas adicionais caso ainda não existam (seed) dbHelper.seedAdditionalCurrencies(); } @@ -28,6 +30,7 @@ public class CurrencyConverter { return amount; } + // Obtém informações das moedas no banco Currency fromCurrency = dbHelper.getCurrencyByCode(fromCurrencyCode); Currency toCurrency = dbHelper.getCurrencyByCode(toCurrencyCode); @@ -35,11 +38,11 @@ public class CurrencyConverter { throw new IllegalArgumentException("Moeda não encontrada"); } - // Converter para USD primeiro, depois para a moeda de destino + // Estratégia: normaliza para USD e depois converte para a moeda destino double amountInUsd = amount / fromCurrency.getRateToUsd(); double result = amountInUsd * toCurrency.getRateToUsd(); - // Salvar no histórico + // Salva a operação no histórico dbHelper.insertConversion(fromCurrencyCode, toCurrencyCode, amount, result); return result; @@ -50,6 +53,7 @@ public class CurrencyConverter { * @return Lista de moedas */ public List getAvailableCurrencies() { + // Lista todas as moedas cadastradas return dbHelper.getAllCurrencies(); } @@ -58,6 +62,7 @@ public class CurrencyConverter { * @return Lista de conversões */ public List getConversionHistory() { + // Retorna as últimas conversões registradas return dbHelper.getConversionHistory(); } @@ -65,6 +70,7 @@ public class CurrencyConverter { * Limpa o histórico de conversões */ public void clearHistory() { + // Limpa todos os registros de conversão dbHelper.clearHistory(); } @@ -74,6 +80,7 @@ public class CurrencyConverter { * @return Objeto Currency ou null se não encontrado */ public Currency getCurrencyByCode(String code) { + // Busca moeda pelo código (ex.: "USD") return dbHelper.getCurrencyByCode(code); } @@ -102,6 +109,7 @@ public class CurrencyConverter { return 1.0; } + // Carrega as moedas e calcula razão das taxas para USD Currency fromCurrency = dbHelper.getCurrencyByCode(fromCurrencyCode); Currency toCurrency = dbHelper.getCurrencyByCode(toCurrencyCode); @@ -122,6 +130,7 @@ public class CurrencyConverter { * @return ID da conversão inserida */ public long insertConversion(String fromCurrency, String toCurrency, double amount, double result) { + // Insere registro manualmente no histórico return dbHelper.insertConversion(fromCurrency, toCurrency, amount, result); } } diff --git a/app/src/main/java/com/example/conversordemoedas2/DatabaseHelper.java b/app/src/main/java/com/example/conversordemoedas2/DatabaseHelper.java index 778861a..17fb28e 100644 --- a/app/src/main/java/com/example/conversordemoedas2/DatabaseHelper.java +++ b/app/src/main/java/com/example/conversordemoedas2/DatabaseHelper.java @@ -8,8 +8,10 @@ import android.database.sqlite.SQLiteOpenHelper; import java.util.ArrayList; import java.util.List; +// ======================= Conversor de Moedas ======================= public class DatabaseHelper extends SQLiteOpenHelper { + // Nome e versão do banco SQLite private static final String DATABASE_NAME = "CurrencyConverter.db"; private static final int DATABASE_VERSION = 1; @@ -35,7 +37,7 @@ public class DatabaseHelper extends SQLiteOpenHelper { @Override public void onCreate(SQLiteDatabase db) { - // Criar tabela de moedas + // Cria a tabela de moedas com taxa relativa ao USD String createCurrenciesTable = "CREATE TABLE " + TABLE_CURRENCIES + " (" + COLUMN_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " + COLUMN_CODE + " TEXT UNIQUE NOT NULL, " + @@ -44,7 +46,7 @@ public class DatabaseHelper extends SQLiteOpenHelper { COLUMN_RATE_TO_USD + " REAL NOT NULL" + ")"; - // Criar tabela de conversões + // Cria a tabela de histórico de conversões String createConversionsTable = "CREATE TABLE " + TABLE_CONVERSIONS + " (" + COLUMN_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " + COLUMN_FROM_CURRENCY + " TEXT NOT NULL, " + @@ -57,7 +59,7 @@ public class DatabaseHelper extends SQLiteOpenHelper { db.execSQL(createCurrenciesTable); db.execSQL(createConversionsTable); - // Inserir moedas padrão + // Insere moedas padrão ao criar o banco (seed inicial) insertDefaultCurrencies(db); } @@ -69,6 +71,7 @@ public class DatabaseHelper extends SQLiteOpenHelper { } private void insertDefaultCurrencies(SQLiteDatabase db) { + // Lista base de moedas com símbolo e taxa para USD String[][] currencies = { {"USD", "Dólar Americano", "$", "1.0"}, {"BRL", "Real Brasileiro", "R$", "5.2"}, @@ -94,6 +97,7 @@ public class DatabaseHelper extends SQLiteOpenHelper { // Métodos para gerenciar moedas public List getAllCurrencies() { + // Retorna todas as moedas ordenadas por nome List currencies = new ArrayList<>(); SQLiteDatabase db = this.getReadableDatabase(); Cursor cursor = db.query(TABLE_CURRENCIES, null, null, null, null, null, COLUMN_NAME); @@ -116,6 +120,7 @@ public class DatabaseHelper extends SQLiteOpenHelper { } public Currency getCurrencyByCode(String code) { + // Busca uma moeda específica pelo código SQLiteDatabase db = this.getReadableDatabase(); Cursor cursor = db.query(TABLE_CURRENCIES, null, COLUMN_CODE + "=?", new String[]{code}, null, null, null); @@ -136,6 +141,7 @@ public class DatabaseHelper extends SQLiteOpenHelper { } public void seedAdditionalCurrencies() { + // Insere moedas adicionais ignorando duplicatas (CONFLICT_IGNORE) SQLiteDatabase db = this.getWritableDatabase(); String[][] more = new String[][]{ {"ARS","Peso Argentino","$","970.0"}, @@ -173,6 +179,7 @@ public class DatabaseHelper extends SQLiteOpenHelper { // Métodos para gerenciar conversões public long insertConversion(String fromCurrency, String toCurrency, double amount, double result) { + // Insere um registro no histórico de conversões SQLiteDatabase db = this.getWritableDatabase(); ContentValues values = new ContentValues(); values.put(COLUMN_FROM_CURRENCY, fromCurrency); @@ -187,6 +194,7 @@ public class DatabaseHelper extends SQLiteOpenHelper { } public List getConversionHistory() { + // Retorna até 50 conversões mais recentes (ordem decrescente por data) List conversions = new ArrayList<>(); SQLiteDatabase db = this.getReadableDatabase(); Cursor cursor = db.query(TABLE_CONVERSIONS, null, null, null, null, null, @@ -211,6 +219,7 @@ public class DatabaseHelper extends SQLiteOpenHelper { } public void clearHistory() { + // Remove todos os registros da tabela de histórico SQLiteDatabase db = this.getWritableDatabase(); db.delete(TABLE_CONVERSIONS, null, null); db.close(); diff --git a/app/src/main/java/com/example/conversordemoedas2/MainActivity.java b/app/src/main/java/com/example/conversordemoedas2/MainActivity.java index c24d24d..945b11d 100644 --- a/app/src/main/java/com/example/conversordemoedas2/MainActivity.java +++ b/app/src/main/java/com/example/conversordemoedas2/MainActivity.java @@ -27,21 +27,34 @@ import com.google.android.material.textfield.TextInputEditText; import java.util.ArrayList; import java.util.List; +// ======================= Conversor de Moedas ======================= public class MainActivity extends AppCompatActivity { - + // Conversor de moedas (regras de negócio e acesso ao banco) private CurrencyConverter currencyConverter; + // Campo de entrada do valor a converter private TextInputEditText amountInput; + // Spinners para seleção de moeda de origem e destino private Spinner fromCurrencySpinner; private Spinner toCurrencySpinner; + // Texto do resultado formatado private TextView resultText; + // Texto que exibe a taxa de câmbio atual entre as moedas private TextView exchangeRateText; + // ========== DECLARAÇÃO DOS BOTÕES (variáveis de classe) ========== + // Botão para limpar o histórico de conversões private MaterialButton clearHistoryButton; + // Lista para exibir o histórico de conversões private ListView historyListView; + // Botão para inverter moeda de origem/destino private ImageView swapButton; + // Botão que abre a tela do conversor de velocidade private MaterialButton speedConverterButton; + // Lista de moedas disponíveis vindas do banco private List currencies; + // Adapter que renderiza os itens do histórico na ListView private ConversionHistoryAdapter historyAdapter; + // Flag para evitar recálculo durante mudanças programáticas nos spinners private boolean isUpdating = false; @Override @@ -55,10 +68,15 @@ public class MainActivity extends AppCompatActivity { return insets; }); + // Inicializa referências de UI (views) initializeViews(); + // Cria o conversor de moedas e carrega a lista de moedas do banco initializeCurrencyConverter(); + // Preenche e configura os spinners de moedas setupSpinners(); + // Registra listeners de botões e do campo de texto setupListeners(); + // Carrega e exibe o histórico salvo no banco loadHistory(); // Executar demonstração no log (opcional) @@ -66,29 +84,36 @@ public class MainActivity extends AppCompatActivity { } private void initializeViews() { + // ========== INICIALIZAÇÃO DOS BOTÕES (vincula com o layout XML) ========== + // Faz o bind das views do layout com os campos da activity amountInput = findViewById(R.id.amountInput); fromCurrencySpinner = findViewById(R.id.fromCurrencySpinner); toCurrencySpinner = findViewById(R.id.toCurrencySpinner); resultText = findViewById(R.id.resultText); exchangeRateText = findViewById(R.id.exchangeRateText); + // Botão limpar histórico - linha 95 clearHistoryButton = findViewById(R.id.clearHistoryButton); historyListView = findViewById(R.id.historyListView); + // Botão trocar moedas - linha 98 swapButton = findViewById(R.id.swapButton); + // Botão abrir conversor de velocidade - linha 100 speedConverterButton = findViewById(R.id.speedConverterButton); } private void initializeCurrencyConverter() { + // Instancia o conversor e busca a lista de moedas disponíveis currencyConverter = new CurrencyConverter(this); currencies = currencyConverter.getAvailableCurrencies(); } private void setupSpinners() { - // Criar lista de strings para os spinners + // Constrói a lista de textos que serão exibidos nos spinners List currencyStrings = new ArrayList<>(); for (Currency currency : currencies) { currencyStrings.add(currency.toString()); } + // Adapter simples padrão Android para popular o spinner ArrayAdapter adapter = new ArrayAdapter<>(this, android.R.layout.simple_spinner_item, currencyStrings); adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); @@ -96,7 +121,7 @@ public class MainActivity extends AppCompatActivity { fromCurrencySpinner.setAdapter(adapter); toCurrencySpinner.setAdapter(adapter); - // Selecionar USD como padrão para origem e BRL para destino + // Define seleção inicial: USD como origem e BRL como destino for (int i = 0; i < currencies.size(); i++) { if (currencies.get(i).getCode().equals("USD")) { fromCurrencySpinner.setSelection(i); @@ -106,7 +131,7 @@ public class MainActivity extends AppCompatActivity { } } - // Atualizar conversão quando as moedas mudarem + // Recalcula quando o usuário altera a moeda de origem fromCurrencySpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { @Override public void onItemSelected(AdapterView parent, View view, int position, long id) { @@ -120,6 +145,7 @@ public class MainActivity extends AppCompatActivity { public void onNothingSelected(AdapterView parent) {} }); + // Recalcula quando o usuário altera a moeda de destino toCurrencySpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { @Override public void onItemSelected(AdapterView parent, View view, int position, long id) { @@ -135,7 +161,8 @@ public class MainActivity extends AppCompatActivity { } private void setupListeners() { - // Conversão automática quando o texto muda + // ========== CONFIGURAÇÃO DOS LISTENERS DOS BOTÕES (o que acontece ao clicar) ========== + // Observa mudanças no campo de valor e recalcula automaticamente amountInput.addTextChangedListener(new TextWatcher() { @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) {} @@ -149,19 +176,19 @@ public class MainActivity extends AppCompatActivity { } }); - // Botão de trocar moedas + // BOTÃO TROCAR MOEDAS - linha 180: ao clicar, chama swapCurrencies() swapButton.setOnClickListener(v -> swapCurrencies()); - // Botão limpar histórico + // BOTÃO LIMPAR HISTÓRICO - linha 183: ao clicar, chama clearHistory() clearHistoryButton.setOnClickListener(v -> clearHistory()); - // Botão conversor de velocidade + // BOTÃO CONVERSOR DE VELOCIDADE - linha 186: ao clicar, abre SpeedConverterActivity speedConverterButton.setOnClickListener(v -> { Intent intent = new Intent(MainActivity.this, SpeedConverterActivity.class); startActivity(intent); }); - // Botão conversor de medidas + // BOTÃO CONVERSOR DE MEDIDAS - linha 192: ao clicar, abre MeasurementConverterActivity MaterialButton measurementConverterButton = findViewById(R.id.measurementConverterButton); measurementConverterButton.setOnClickListener(v -> { Intent intent = new Intent(MainActivity.this, MeasurementConverterActivity.class); @@ -170,6 +197,7 @@ public class MainActivity extends AppCompatActivity { } private void updateConversion() { + // Validação básica do texto digitado String amountString = amountInput.getText().toString().trim(); if (TextUtils.isEmpty(amountString)) { @@ -179,6 +207,7 @@ public class MainActivity extends AppCompatActivity { } try { + // Converte string para número e valida sinal double amount = Double.parseDouble(amountString); if (amount <= 0) { @@ -187,20 +216,21 @@ public class MainActivity extends AppCompatActivity { return; } + // Obtém moedas selecionadas e realiza a conversão Currency fromCurrency = currencies.get(fromCurrencySpinner.getSelectedItemPosition()); Currency toCurrency = currencies.get(toCurrencySpinner.getSelectedItemPosition()); double result = currencyConverter.convert(amount, fromCurrency.getCode(), toCurrency.getCode()); - // Mostrar resultado com animação + // Formata e exibe o resultado String formattedResult = currencyConverter.formatCurrency(result, toCurrency.getCode()); resultText.setText(formattedResult); resultText.setTextColor(getResources().getColor(R.color.primary_color)); - // Animação suave + // Efeito visual simples para destacar atualização resultText.startAnimation(AnimationUtils.loadAnimation(this, android.R.anim.fade_in)); - // Salvar no histórico apenas se for uma conversão válida + // Persiste no histórico e atualiza a lista if (amount > 0) { currencyConverter.insertConversion(fromCurrency.getCode(), toCurrency.getCode(), amount, result); loadHistory(); @@ -216,6 +246,7 @@ public class MainActivity extends AppCompatActivity { } private void swapCurrencies() { + // Evita disparar listeners durante a troca programática isUpdating = true; int fromPosition = fromCurrencySpinner.getSelectedItemPosition(); @@ -224,12 +255,12 @@ public class MainActivity extends AppCompatActivity { fromCurrencySpinner.setSelection(toPosition); toCurrencySpinner.setSelection(fromPosition); - // Animação do botão + // Realça o clique no botão de troca swapButton.startAnimation(AnimationUtils.loadAnimation(this, android.R.anim.fade_in)); isUpdating = false; - // Atualizar conversão após a troca + // Recalcula e atualiza taxa após a troca updateConversion(); updateExchangeRate(); @@ -238,6 +269,7 @@ public class MainActivity extends AppCompatActivity { private void updateExchangeRate() { try { + // Calcula e exibe a taxa de câmbio 1:1 entre as moedas Currency fromCurrency = currencies.get(fromCurrencySpinner.getSelectedItemPosition()); Currency toCurrency = currencies.get(toCurrencySpinner.getSelectedItemPosition()); @@ -253,12 +285,14 @@ public class MainActivity extends AppCompatActivity { } private void loadHistory() { + // Consulta o banco e popula o adapter da ListView List history = currencyConverter.getConversionHistory(); historyAdapter = new ConversionHistoryAdapter(this, history); historyListView.setAdapter(historyAdapter); } private void clearHistory() { + // Apaga todos os registros da tabela de histórico currencyConverter.clearHistory(); loadHistory(); Toast.makeText(this, "Histórico limpo", Toast.LENGTH_SHORT).show(); diff --git a/app/src/main/java/com/example/conversordemoedas2/MeasurementConverter.java b/app/src/main/java/com/example/conversordemoedas2/MeasurementConverter.java index 69f619e..a44efc2 100644 --- a/app/src/main/java/com/example/conversordemoedas2/MeasurementConverter.java +++ b/app/src/main/java/com/example/conversordemoedas2/MeasurementConverter.java @@ -6,21 +6,25 @@ import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +// ======================= Conversor de Medidas ======================= public class MeasurementConverter { + // Nomes de categorias suportadas private static final String CAT_LENGTH = "Comprimento"; private static final String CAT_WEIGHT = "Peso"; private static final String CAT_TEMPERATURE = "Temperatura"; + // Unidades disponíveis por categoria private static final List LENGTH_UNITS = Arrays.asList("mm","cm","m","km","in","ft","yd","mi"); private static final List WEIGHT_UNITS = Arrays.asList("mg","g","kg","t","oz","lb"); private static final List TEMP_UNITS = Arrays.asList("°C","°F","K"); + // Fatores para converter para a unidade base (metro e quilograma) private static final Map LENGTH_TO_METER = new LinkedHashMap<>(); private static final Map WEIGHT_TO_KG = new LinkedHashMap<>(); static { - // Comprimento -> metros + // Comprimento -> fator para metros LENGTH_TO_METER.put("mm", 0.001); LENGTH_TO_METER.put("cm", 0.01); LENGTH_TO_METER.put("m", 1.0); @@ -30,7 +34,7 @@ public class MeasurementConverter { LENGTH_TO_METER.put("yd", 0.9144); LENGTH_TO_METER.put("mi", 1609.344); - // Peso -> quilogramas + // Peso -> fator para quilogramas WEIGHT_TO_KG.put("mg", 0.000001); WEIGHT_TO_KG.put("g", 0.001); WEIGHT_TO_KG.put("kg", 1.0); @@ -40,6 +44,7 @@ public class MeasurementConverter { } public List getUnitsForCategory(String category) { + // Retorna a lista de unidades correspondente à categoria if (CAT_LENGTH.equals(category)) return new ArrayList<>(LENGTH_UNITS); if (CAT_WEIGHT.equals(category)) return new ArrayList<>(WEIGHT_UNITS); if (CAT_TEMPERATURE.equals(category)) return new ArrayList<>(TEMP_UNITS); @@ -47,17 +52,20 @@ public class MeasurementConverter { } public double convert(String category, double value, String from, String to) { + // Atalho: mesma unidade não precisa converter if (from.equals(to)) return value; if (CAT_LENGTH.equals(category)) { + // Normaliza para metros e depois para a unidade destino double meters = value * LENGTH_TO_METER.get(from); return meters / LENGTH_TO_METER.get(to); } if (CAT_WEIGHT.equals(category)) { + // Normaliza para quilogramas e depois para a unidade destino double kg = value * WEIGHT_TO_KG.get(from); return kg / WEIGHT_TO_KG.get(to); } if (CAT_TEMPERATURE.equals(category)) { - // normalize to Celsius + // Normaliza para Celsius e reconverte double c; if ("°C".equals(from)) c = value; else if ("°F".equals(from)) c = (value - 32.0) * 5.0 / 9.0; @@ -70,6 +78,7 @@ public class MeasurementConverter { } public double rate(String category, String from, String to) { + // Taxa unitária entre duas unidades (constante p/ comprimento/peso) if (from.equals(to)) return 1.0; if (CAT_LENGTH.equals(category)) { return LENGTH_TO_METER.get(from) / LENGTH_TO_METER.get(to); @@ -78,16 +87,18 @@ public class MeasurementConverter { return WEIGHT_TO_KG.get(from) / WEIGHT_TO_KG.get(to); } if (CAT_TEMPERATURE.equals(category)) { - // temperature rates aren't constant; show delta conversion for 1 unit + // Temperatura não tem fator constante; mostra conversão de 1 unidade return convert(category, 1.0, from, to); } return 1.0; } public String format(String category, double value, String unit) { + // Formatação: temperatura com 2 casas, demais com 4 if (CAT_TEMPERATURE.equals(category)) { return String.format("%.2f %s", value, unit); } return String.format("%.4f %s", value, unit); } } + diff --git a/app/src/main/java/com/example/conversordemoedas2/MeasurementConverterActivity.java b/app/src/main/java/com/example/conversordemoedas2/MeasurementConverterActivity.java index bd7c4a0..8d5d342 100644 --- a/app/src/main/java/com/example/conversordemoedas2/MeasurementConverterActivity.java +++ b/app/src/main/java/com/example/conversordemoedas2/MeasurementConverterActivity.java @@ -22,16 +22,21 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; +// ======================= Conversor de Medidas ======================= public class MeasurementConverterActivity extends AppCompatActivity { + // Classe com as regras de negócio para medidas private MeasurementConverter measurementConverter; + // Spinners para categoria (Comprimento/Peso/Temperatura) e unidades private Spinner categorySpinner; private Spinner fromUnitSpinner; private Spinner toUnitSpinner; + // Campo de entrada e textos de resultado/taxa private TextInputEditText amountInput; private TextView resultText; private TextView rateText; + // Lista de categorias suportadas private List categories; @Override @@ -45,6 +50,7 @@ public class MeasurementConverterActivity extends AppCompatActivity { return insets; }); + // Inicializa views e lógica e registra listeners initializeViews(); initializeConverter(); setupCategorySpinner(); @@ -52,6 +58,8 @@ public class MeasurementConverterActivity extends AppCompatActivity { } private void initializeViews() { + // ========== INICIALIZAÇÃO DOS BOTÕES (vincula com o layout XML) ========== + // Faz o bind das views do layout categorySpinner = findViewById(R.id.categorySpinner); fromUnitSpinner = findViewById(R.id.measureFromUnitSpinner); toUnitSpinner = findViewById(R.id.measureToUnitSpinner); @@ -59,25 +67,31 @@ public class MeasurementConverterActivity extends AppCompatActivity { resultText = findViewById(R.id.measureResultText); rateText = findViewById(R.id.measureRateText); + // ========== CONFIGURAÇÃO DOS LISTENERS DOS BOTÕES (o que acontece ao clicar) ========== + // BOTÃO ABRIR CONVERSOR DE MOEDAS - linha 72: ao clicar, abre MainActivity findViewById(R.id.openCurrencyConverterButton).setOnClickListener(v -> { startActivity(new android.content.Intent(this, MainActivity.class)); }); + // BOTÃO ABRIR CONVERSOR DE VELOCIDADE - linha 76: ao clicar, abre SpeedConverterActivity findViewById(R.id.openSpeedConverterButton).setOnClickListener(v -> { startActivity(new android.content.Intent(this, SpeedConverterActivity.class)); }); } private void initializeConverter() { + // Instancia as regras e define categorias disponíveis measurementConverter = new MeasurementConverter(); categories = new ArrayList<>(Arrays.asList("Comprimento", "Peso", "Temperatura")); } private void setupCategorySpinner() { + // Popula spinner de categorias ArrayAdapter categoryAdapter = new ArrayAdapter<>(this, android.R.layout.simple_spinner_item, categories); categoryAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); categorySpinner.setAdapter(categoryAdapter); + // Ao trocar a categoria, atualiza unidades, conversão e taxa categorySpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { @Override public void onItemSelected(AdapterView parent, android.view.View view, int position, long id) { @@ -91,6 +105,7 @@ public class MeasurementConverterActivity extends AppCompatActivity { } private void populateUnits() { + // Carrega unidades de acordo com a categoria selecionada e popular spinners String category = (String) categorySpinner.getSelectedItem(); List units = measurementConverter.getUnitsForCategory(category); ArrayAdapter unitsAdapter = new ArrayAdapter<>(this, @@ -98,10 +113,12 @@ public class MeasurementConverterActivity extends AppCompatActivity { unitsAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); fromUnitSpinner.setAdapter(unitsAdapter); toUnitSpinner.setAdapter(unitsAdapter); + // Seleção inicial: primeira e segunda unidade da lista if (!units.isEmpty()) { fromUnitSpinner.setSelection(0); toUnitSpinner.setSelection(Math.min(1, units.size() - 1)); } + // Reage a trocas de unidade fromUnitSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { @Override public void onItemSelected(AdapterView parent, android.view.View view, int position, long id) { @@ -123,6 +140,7 @@ public class MeasurementConverterActivity extends AppCompatActivity { } private void setupListeners() { + // Observa mudanças no valor digitado e recalcula amountInput.addTextChangedListener(new TextWatcher() { @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) {} @Override public void onTextChanged(CharSequence s, int start, int before, int count) {} @@ -131,6 +149,7 @@ public class MeasurementConverterActivity extends AppCompatActivity { } private void updateConversion() { + // Lê e valida o valor de entrada String input = amountInput.getText() != null ? amountInput.getText().toString().trim() : ""; if (TextUtils.isEmpty(input)) { resultText.setText("Digite um valor para converter"); @@ -138,6 +157,7 @@ public class MeasurementConverterActivity extends AppCompatActivity { return; } try { + // Aplica conversão conforme categoria e unidades selecionadas double value = Double.parseDouble(input); String category = (String) categorySpinner.getSelectedItem(); String from = (String) fromUnitSpinner.getSelectedItem(); @@ -158,6 +178,7 @@ public class MeasurementConverterActivity extends AppCompatActivity { private void updateRate() { try { + // Exibe a taxa de conversão (constante p/ comprimento/peso e referencial p/ temperatura) String category = (String) categorySpinner.getSelectedItem(); String from = (String) fromUnitSpinner.getSelectedItem(); String to = (String) toUnitSpinner.getSelectedItem(); diff --git a/app/src/main/java/com/example/conversordemoedas2/SpeedConverter.java b/app/src/main/java/com/example/conversordemoedas2/SpeedConverter.java index 540b248..ebffa0a 100644 --- a/app/src/main/java/com/example/conversordemoedas2/SpeedConverter.java +++ b/app/src/main/java/com/example/conversordemoedas2/SpeedConverter.java @@ -4,8 +4,10 @@ import android.content.Context; import java.util.ArrayList; import java.util.List; +// ======================= Conversor de Velocidade ======================= public class SpeedConverter { + // Helper do banco (não usado para velocidade, mas mantido para consistência/expansão) private DatabaseHelper dbHelper; // Unidades de velocidade com fatores de conversão para m/s (metros por segundo) @@ -39,6 +41,7 @@ public class SpeedConverter { return value; } + // Obtém fatores de normalização para m/s double fromFactor = getFactor(fromUnit); double toFactor = getFactor(toUnit); @@ -46,7 +49,7 @@ public class SpeedConverter { throw new IllegalArgumentException("Unidade não encontrada"); } - // Converter para m/s primeiro, depois para a unidade de destino + // Converte para m/s e em seguida para a unidade alvo double valueInMs = value * fromFactor; double result = valueInMs / toFactor; @@ -59,6 +62,7 @@ public class SpeedConverter { * @return Fator de conversão */ private double getFactor(String unit) { + // Busca o fator correspondente ao símbolo informado for (Object[] speedUnit : SPEED_UNITS) { if (speedUnit[1].equals(unit)) { return (Double) speedUnit[2]; @@ -72,6 +76,7 @@ public class SpeedConverter { * @return Lista de unidades */ public List getAvailableUnits() { + // Constrói objetos de unidade a partir da tabela estática List units = new ArrayList<>(); for (Object[] speedUnit : SPEED_UNITS) { units.add(new SpeedUnit( @@ -90,6 +95,7 @@ public class SpeedConverter { * @return Objeto SpeedUnit ou null se não encontrado */ public SpeedUnit getUnitByCode(String code) { + // Retorna a unidade cujo símbolo corresponde ao código for (Object[] speedUnit : SPEED_UNITS) { if (speedUnit[1].equals(code)) { return new SpeedUnit( @@ -110,6 +116,7 @@ public class SpeedConverter { * @return String formatada */ public String formatSpeed(double value, String unitCode) { + // Formata com 2 casas e anexa o símbolo da unidade SpeedUnit unit = getUnitByCode(unitCode); if (unit != null) { return String.format("%.2f %s", value, unit.getSymbol()); @@ -128,6 +135,7 @@ public class SpeedConverter { return 1.0; } + // Razão direta entre fatores para m/s double fromFactor = getFactor(fromUnit); double toFactor = getFactor(toUnit); @@ -143,6 +151,7 @@ public class SpeedConverter { * @return Lista de exemplos */ public List getExamples() { + // Exemplos didáticos para demonstrar conversões comuns List examples = new ArrayList<>(); examples.add("🚗 100 km/h = 27.78 m/s"); examples.add("✈️ 500 mph = 223.52 m/s"); diff --git a/app/src/main/java/com/example/conversordemoedas2/SpeedConverterActivity.java b/app/src/main/java/com/example/conversordemoedas2/SpeedConverterActivity.java index 0289c94..1946772 100644 --- a/app/src/main/java/com/example/conversordemoedas2/SpeedConverterActivity.java +++ b/app/src/main/java/com/example/conversordemoedas2/SpeedConverterActivity.java @@ -24,17 +24,25 @@ import com.google.android.material.textfield.TextInputEditText; import java.util.ArrayList; import java.util.List; +// ======================= Conversor de Velocidade ======================= public class SpeedConverterActivity extends AppCompatActivity { - + // Classe responsável por converter valores entre unidades de velocidade private SpeedConverter speedConverter; + // Campo de entrada do valor de velocidade private TextInputEditText speedAmountInput; + // Spinners para selecionar unidade de origem e destino private Spinner fromSpeedSpinner; private Spinner toSpeedSpinner; + // Textos para exibir resultado e taxa private TextView speedResultText; private TextView speedRateText; + // ========== DECLARAÇÃO DOS BOTÕES (variáveis de classe) ========== + // Botão para inverter unidades private ImageView speedSwapButton; + // Lista de unidades disponíveis (com símbolo, nome e fator) private List speedUnits; + // Flag de controle para evitar eventos durante trocas programáticas private boolean isUpdating = false; @Override @@ -47,9 +55,11 @@ public class SpeedConverterActivity extends AppCompatActivity { v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom); return insets; }); - // Removida Toolbar! + // ========== BOTÃO VOLTAR (configurado diretamente no onCreate) ========== + // Botão para voltar ao conversor de moedas (fecha a tela) - linha 58 findViewById(R.id.currencyConverterButton).setOnClickListener(v -> finish()); + // Inicializa views, lógica e listeners initializeViews(); initializeSpeedConverter(); setupSpinners(); @@ -57,26 +67,31 @@ public class SpeedConverterActivity extends AppCompatActivity { } private void initializeViews() { + // ========== INICIALIZAÇÃO DOS BOTÕES (vincula com o layout XML) ========== + // Faz o bind das views do layout speedAmountInput = findViewById(R.id.speedAmountInput); fromSpeedSpinner = findViewById(R.id.speedFromUnitSpinner); toSpeedSpinner = findViewById(R.id.speedToUnitSpinner); speedResultText = findViewById(R.id.speedResultText); speedRateText = findViewById(R.id.speedRateText); + // Botão trocar unidades - linha 78 speedSwapButton = findViewById(R.id.speedSwapButton); } private void initializeSpeedConverter() { + // Instancia o conversor e carrega unidades disponíveis speedConverter = new SpeedConverter(this); speedUnits = speedConverter.getAvailableUnits(); } private void setupSpinners() { - // Criar lista de strings para os spinners + // Cria a lista textual para exibir cada unidade no spinner List unitStrings = new ArrayList<>(); for (SpeedUnit unit : speedUnits) { unitStrings.add(unit.toString()); } + // Usa adapter simples padrão do Android ArrayAdapter adapter = new ArrayAdapter<>(this, android.R.layout.simple_spinner_item, unitStrings); adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); @@ -84,7 +99,7 @@ public class SpeedConverterActivity extends AppCompatActivity { fromSpeedSpinner.setAdapter(adapter); toSpeedSpinner.setAdapter(adapter); - // Selecionar m/s como padrão para origem e km/h para destino + // Define seleção inicial: m/s como origem e km/h como destino for (int i = 0; i < speedUnits.size(); i++) { if (speedUnits.get(i).getSymbol().equals("m/s")) { fromSpeedSpinner.setSelection(i); @@ -94,7 +109,7 @@ public class SpeedConverterActivity extends AppCompatActivity { } } - // Atualizar conversão quando as unidades mudarem + // Recalcula quando a unidade de origem muda fromSpeedSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { @Override public void onItemSelected(AdapterView parent, View view, int position, long id) { @@ -108,6 +123,7 @@ public class SpeedConverterActivity extends AppCompatActivity { public void onNothingSelected(AdapterView parent) {} }); + // Recalcula quando a unidade de destino muda toSpeedSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { @Override public void onItemSelected(AdapterView parent, View view, int position, long id) { @@ -123,7 +139,8 @@ public class SpeedConverterActivity extends AppCompatActivity { } private void setupListeners() { - // Conversão automática quando o texto muda + // ========== CONFIGURAÇÃO DOS LISTENERS DOS BOTÕES (o que acontece ao clicar) ========== + // Observa alterações no campo de texto e recalcula automaticamente speedAmountInput.addTextChangedListener(new TextWatcher() { @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) {} @@ -137,11 +154,12 @@ public class SpeedConverterActivity extends AppCompatActivity { } }); - // Botão de trocar unidades + // BOTÃO TROCAR UNIDADES - linha 157: ao clicar, chama swapUnits() speedSwapButton.setOnClickListener(v -> swapUnits()); } private void updateConversion() { + // Lê e valida o valor digitado String amountString = speedAmountInput.getText().toString().trim(); if (TextUtils.isEmpty(amountString)) { @@ -151,6 +169,7 @@ public class SpeedConverterActivity extends AppCompatActivity { } try { + // Converte para número e valida sinal (não negativo) double amount = Double.parseDouble(amountString); if (amount < 0) { @@ -159,17 +178,18 @@ public class SpeedConverterActivity extends AppCompatActivity { return; } + // Obtém as unidades selecionadas e delega a conversão para a classe de regras SpeedUnit fromUnit = speedUnits.get(fromSpeedSpinner.getSelectedItemPosition()); SpeedUnit toUnit = speedUnits.get(toSpeedSpinner.getSelectedItemPosition()); double result = speedConverter.convert(amount, fromUnit.getSymbol(), toUnit.getSymbol()); - // Mostrar resultado com animação + // Formata e exibe o resultado da conversão String formattedResult = speedConverter.formatSpeed(result, toUnit.getSymbol()); speedResultText.setText(formattedResult); speedResultText.setTextColor(getResources().getColor(R.color.accent_color)); - // Animação suave + // Efeito visual simples para indicar atualização speedResultText.startAnimation(AnimationUtils.loadAnimation(this, android.R.anim.fade_in)); } catch (NumberFormatException e) { @@ -182,6 +202,7 @@ public class SpeedConverterActivity extends AppCompatActivity { } private void swapUnits() { + // Evita disparar eventos durante troca programática isUpdating = true; int fromPosition = fromSpeedSpinner.getSelectedItemPosition(); @@ -190,18 +211,19 @@ public class SpeedConverterActivity extends AppCompatActivity { fromSpeedSpinner.setSelection(toPosition); toSpeedSpinner.setSelection(fromPosition); - // Animação do botão + // Feedback visual do clique speedSwapButton.startAnimation(AnimationUtils.loadAnimation(this, android.R.anim.fade_in)); isUpdating = false; - // Atualizar conversão após a troca + // Recalcula valores e taxa após a troca updateConversion(); updateRate(); } private void updateRate() { try { + // Calcula a taxa de conversão entre as unidades selecionadas SpeedUnit fromUnit = speedUnits.get(fromSpeedSpinner.getSelectedItemPosition()); SpeedUnit toUnit = speedUnits.get(toSpeedSpinner.getSelectedItemPosition()); diff --git a/app/src/main/java/com/example/conversordemoedas2/SpeedUnit.java b/app/src/main/java/com/example/conversordemoedas2/SpeedUnit.java index 00cc629..e81f4af 100644 --- a/app/src/main/java/com/example/conversordemoedas2/SpeedUnit.java +++ b/app/src/main/java/com/example/conversordemoedas2/SpeedUnit.java @@ -1,9 +1,14 @@ package com.example.conversordemoedas2; +// ======================= Conversor de Velocidade ======================= public class SpeedUnit { + // Identificador interno private int id; + // Símbolo curto da unidade (ex.: km/h) private String symbol; + // Nome descritivo (ex.: Quilômetros por hora) private String name; + // Fator para converter para m/s private double factorToMs; public SpeedUnit(int id, String symbol, String name, double factorToMs) { @@ -27,6 +32,7 @@ public class SpeedUnit { @Override public String toString() { + // Exibe símbolo e nome, usado nos spinners return symbol + " - " + name; } } @@ -34,3 +40,4 @@ public class SpeedUnit { + diff --git a/app/src/main/res/drawable/circle_background.xml b/app/src/main/res/drawable/circle_background.xml index 4c17115..b29d818 100644 --- a/app/src/main/res/drawable/circle_background.xml +++ b/app/src/main/res/drawable/circle_background.xml @@ -8,3 +8,5 @@ + + diff --git a/app/src/main/res/drawable/circle_background_speed.xml b/app/src/main/res/drawable/circle_background_speed.xml deleted file mode 100644 index e250c95..0000000 --- a/app/src/main/res/drawable/circle_background_speed.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - diff --git a/app/src/main/res/drawable/ic_arrow_back.xml b/app/src/main/res/drawable/ic_arrow_back.xml index 04acb54..1e55670 100644 --- a/app/src/main/res/drawable/ic_arrow_back.xml +++ b/app/src/main/res/drawable/ic_arrow_back.xml @@ -9,3 +9,5 @@ android:pathData="M20,11H7.83l5.58-5.59L12,4l-8,8 8,8 1.41-1.41L7.83,13H20v-2z"/> + + diff --git a/app/src/main/res/drawable/ic_swap.xml b/app/src/main/res/drawable/ic_swap.xml index 5e30b65..ffb3153 100644 --- a/app/src/main/res/drawable/ic_swap.xml +++ b/app/src/main/res/drawable/ic_swap.xml @@ -13,3 +13,5 @@ + + diff --git a/app/src/main/res/drawable/spinner_background.xml b/app/src/main/res/drawable/spinner_background.xml index fbc31d5..87d8837 100644 --- a/app/src/main/res/drawable/spinner_background.xml +++ b/app/src/main/res/drawable/spinner_background.xml @@ -9,3 +9,5 @@ + + diff --git a/app/src/main/res/layout/fragment_measurement_converter.xml b/app/src/main/res/layout/fragment_measurement_converter.xml index 5b2cf9d..4414cce 100644 --- a/app/src/main/res/layout/fragment_measurement_converter.xml +++ b/app/src/main/res/layout/fragment_measurement_converter.xml @@ -58,40 +58,29 @@ - + android:layout_marginBottom="8dp" + android:text="💱 Conversor de Moedas" + android:textSize="16sp" + android:textStyle="bold" + android:padding="16dp" + app:cornerRadius="12dp" + app:backgroundTint="@color/primary_color" /> - - - - - - +