From 57372a537976fd7bb0aa654f3814a73827538275 Mon Sep 17 00:00:00 2001
From: 230402 <230402@epvc.pt>
Date: Mon, 11 May 2026 17:17:56 +0100
Subject: [PATCH] =?UTF-8?q?Corre=C3=A7=C3=A3o=20de=20bugs=20e=20melhoramen?=
=?UTF-8?q?to=20de=20design?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
app/src/main/AndroidManifest.xml | 2 +
.../finzora/AlterarPasswordActivity.java | 57 ++
.../example/finzora/DefinicoesActivity.java | 37 +-
.../com/example/finzora/DicasFragment.java | 250 ++++----
.../example/finzora/EditarPerfilActivity.java | 16 +-
.../com/example/finzora/GraficosFragment.java | 70 ++-
.../com/example/finzora/MainActivity.java | 5 -
app/src/main/res/drawable/ic_bell.xml | 10 +
.../main/res/drawable/ic_chevron_right.xml | 10 +
.../main/res/drawable/ic_delete_forever.xml | 10 +
app/src/main/res/drawable/ic_edit_profile.xml | 10 +
app/src/main/res/drawable/ic_fingerprint.xml | 10 +
app/src/main/res/drawable/ic_lock.xml | 10 +
app/src/main/res/drawable/ic_logout.xml | 10 +
app/src/main/res/drawable/ic_moon.xml | 10 +
app/src/main/res/drawable/ic_support.xml | 10 +
.../res/layout/activity_alterar_password.xml | 153 +++++
.../main/res/layout/activity_definicoes.xml | 441 ++++++++++---
.../res/layout/activity_editar_perfil.xml | 237 ++++---
app/src/main/res/layout/activity_main.xml | 115 ++--
app/src/main/res/layout/fragment_dicas.xml | 595 +++++++++---------
app/src/main/res/layout/fragment_graficos.xml | 177 ++++--
.../main/res/layout/fragment_objetivos.xml | 39 +-
.../main/res/layout/fragment_orcamento.xml | 129 ++--
.../main/res/layout/fragment_transacoes.xml | 55 +-
app/src/main/res/layout/item_objetivo.xml | 84 +--
app/src/main/res/layout/item_orcamento.xml | 40 +-
27 files changed, 1657 insertions(+), 935 deletions(-)
create mode 100644 app/src/main/java/com/example/finzora/AlterarPasswordActivity.java
create mode 100644 app/src/main/res/drawable/ic_bell.xml
create mode 100644 app/src/main/res/drawable/ic_chevron_right.xml
create mode 100644 app/src/main/res/drawable/ic_delete_forever.xml
create mode 100644 app/src/main/res/drawable/ic_edit_profile.xml
create mode 100644 app/src/main/res/drawable/ic_fingerprint.xml
create mode 100644 app/src/main/res/drawable/ic_lock.xml
create mode 100644 app/src/main/res/drawable/ic_logout.xml
create mode 100644 app/src/main/res/drawable/ic_moon.xml
create mode 100644 app/src/main/res/drawable/ic_support.xml
create mode 100644 app/src/main/res/layout/activity_alterar_password.xml
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index e078032..522f5c7 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -48,6 +48,8 @@
+
+
diff --git a/app/src/main/java/com/example/finzora/AlterarPasswordActivity.java b/app/src/main/java/com/example/finzora/AlterarPasswordActivity.java
new file mode 100644
index 0000000..d3222bc
--- /dev/null
+++ b/app/src/main/java/com/example/finzora/AlterarPasswordActivity.java
@@ -0,0 +1,57 @@
+package com.example.finzora;
+
+import android.os.Bundle;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.ImageView;
+import android.widget.Toast;
+
+import androidx.appcompat.app.AppCompatActivity;
+
+public class AlterarPasswordActivity extends AppCompatActivity {
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_alterar_password);
+
+ ImageView btnVoltar = findViewById(R.id.btnVoltarPassword);
+ EditText editPasswordAtual = findViewById(R.id.editPasswordAtual);
+ EditText editPasswordNova = findViewById(R.id.editPasswordNova);
+ EditText editPasswordConfirmar = findViewById(R.id.editPasswordConfirmar);
+ Button btnGuardar = findViewById(R.id.btnGuardarPassword);
+
+ // Voltar atrás
+ btnVoltar.setOnClickListener(v -> finish());
+
+ // Guardar Nova Palavra-passe
+ btnGuardar.setOnClickListener(v -> {
+ String passAtual = editPasswordAtual.getText().toString();
+ String passNova = editPasswordNova.getText().toString();
+ String passConfirma = editPasswordConfirmar.getText().toString();
+
+ // 1. Validar se os campos estão preenchidos
+ if (passAtual.isEmpty() || passNova.isEmpty() || passConfirma.isEmpty()) {
+ Toast.makeText(this, "Preenche todos os campos!", Toast.LENGTH_SHORT).show();
+ return;
+ }
+
+ // 2. Validar o tamanho
+ if (passNova.length() < 6) {
+ editPasswordNova.setError("Tem de ter pelo menos 6 caracteres");
+ return;
+ }
+
+ // 3. Validar se as palavras-passe novas coincidem
+ if (!passNova.equals(passConfirma)) {
+ editPasswordConfirmar.setError("As palavras-passe não coincidem!");
+ return;
+ }
+
+ // AQUI DEVE ENTRAR O TEU CÓDIGO DO SUPABASE PARA MUDAR A PASS!
+ // Por agora, damos a sensação de sucesso:
+ Toast.makeText(this, "Palavra-passe atualizada com segurança! 🔒", Toast.LENGTH_LONG).show();
+ finish();
+ });
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/example/finzora/DefinicoesActivity.java b/app/src/main/java/com/example/finzora/DefinicoesActivity.java
index 5d94f09..dfab991 100644
--- a/app/src/main/java/com/example/finzora/DefinicoesActivity.java
+++ b/app/src/main/java/com/example/finzora/DefinicoesActivity.java
@@ -11,13 +11,15 @@ import android.net.Uri;
import android.os.Bundle;
import android.view.ViewGroup;
import android.widget.Button;
-import android.widget.Switch;
-import android.widget.TextView;
+import android.widget.LinearLayout;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.app.AppCompatDelegate;
+import androidx.appcompat.widget.Toolbar;
+
+import com.google.android.material.switchmaterial.SwitchMaterial;
import java.io.IOException;
@@ -36,20 +38,21 @@ public class DefinicoesActivity extends AppCompatActivity {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_definicoes);
- TextView btnVoltarDefinicoes = findViewById(R.id.btnVoltarDefinicoes);
- TextView btnEditarPerfil = findViewById(R.id.btnEditarPerfil);
- Switch switchModoEscuro = findViewById(R.id.switchModoEscuro);
- Switch switchNotificacoes = findViewById(R.id.switchNotificacoes);
- Switch switchBiometria = findViewById(R.id.switchBiometria);
- TextView btnSuporte = findViewById(R.id.btnSuporte);
+ // --- VINCULAR OS NOVOS JOGADORES DO DESIGN PREMIUM ---
+ Toolbar toolbar = findViewById(R.id.toolbarDefinicoes);
+ LinearLayout itemEditarPerfil = findViewById(R.id.itemEditarPerfil);
+ SwitchMaterial switchModoEscuro = findViewById(R.id.switchModoEscuro);
+ SwitchMaterial switchNotificacoes = findViewById(R.id.switchNotificacoes);
+ SwitchMaterial switchBiometria = findViewById(R.id.switchBiometria);
+ LinearLayout itemCentroSuporte = findViewById(R.id.itemCentroSuporte);
Button btnTerminarSessao = findViewById(R.id.btnTerminarSessao);
- Button btnEliminarConta = findViewById(R.id.btnEliminarConta);
+ Button btnApagarConta = findViewById(R.id.btnApagarConta);
- // --- 0. BOTÃO DE VOLTAR ---
- btnVoltarDefinicoes.setOnClickListener(v -> finish());
+ // --- 0. BOTÃO DE VOLTAR (Na nova Toolbar) ---
+ toolbar.setNavigationOnClickListener(v -> finish());
- // --- 1. EDITAR PERFIL ---
- btnEditarPerfil.setOnClickListener(v -> {
+ // --- 1. EDITAR PERFIL (Agora é um item clicável) ---
+ itemEditarPerfil.setOnClickListener(v -> {
startActivity(new Intent(DefinicoesActivity.this, EditarPerfilActivity.class));
});
@@ -95,13 +98,13 @@ public class DefinicoesActivity extends AppCompatActivity {
});
// --- 5. CENTRO DE SUPORTE (POP-UP) ---
- btnSuporte.setOnClickListener(v -> mostrarDialogSuporte());
+ itemCentroSuporte.setOnClickListener(v -> mostrarDialogSuporte());
// --- 6. TERMINAR SESSÃO ---
btnTerminarSessao.setOnClickListener(v -> terminarSessao());
// --- 7. APAGAR CONTA ---
- btnEliminarConta.setOnClickListener(v -> mostrarAvisoEliminar());
+ btnApagarConta.setOnClickListener(v -> mostrarAvisoEliminar());
}
private void mostrarAvisoEliminar() {
@@ -225,7 +228,7 @@ public class DefinicoesActivity extends AppCompatActivity {
enviarEmailProfissional();
});
- // 📞 CONTACTOS DIRETOS: Abre o nosso Novo Design Premium!
+ // 📞 CONTACTOS DIRETOS
dialog.findViewById(R.id.cardContactos).setOnClickListener(v -> {
dialog.dismiss();
mostrarDialogContactosInfo();
@@ -234,7 +237,6 @@ public class DefinicoesActivity extends AppCompatActivity {
dialog.show();
}
- // 🏆 A NOVA FUNÇÃO QUE CHAMA O DESIGN PREMIUM
private void mostrarDialogContactosInfo() {
Dialog dialog = new Dialog(this);
dialog.setContentView(R.layout.dialog_contactos);
@@ -244,7 +246,6 @@ public class DefinicoesActivity extends AppCompatActivity {
dialog.getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
}
- // Quando clica em Voltar, fechamos este e abrimos o menu de Suporte outra vez!
dialog.findViewById(R.id.btnFecharContactos).setOnClickListener(v -> {
dialog.dismiss();
mostrarDialogSuporte();
diff --git a/app/src/main/java/com/example/finzora/DicasFragment.java b/app/src/main/java/com/example/finzora/DicasFragment.java
index c3b2edf..d02c56b 100644
--- a/app/src/main/java/com/example/finzora/DicasFragment.java
+++ b/app/src/main/java/com/example/finzora/DicasFragment.java
@@ -9,11 +9,13 @@ import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
+import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
-import android.widget.ImageButton;
+import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.TextView;
+import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
@@ -38,19 +40,20 @@ import okhttp3.Response;
public class DicasFragment extends Fragment {
- private TextView tvTaxaPoupanca, tvDicasReceitas, tvDicasDespesas;
- private ProgressBar progressPoupanca;
- private TextView tvTituloDica1, tvDescDica1, tvTituloDica2, tvDescDica2, tvTituloDica3, tvDescDica3;
- private LinearLayout layoutDistribuicao;
-
- private View layoutConteudoDicas;
- private View layoutEstadoVazioDicas;
-
- private TextView tvRespostaAI;
+ // IA
private EditText editPerguntaAI;
- private ImageButton btnEnviarAI;
- private ProgressBar pbCarregandoAI;
+ private ImageView btnEnviarAI;
+ private TextView tvRespostaAI; // 🚀 Adicionámos o jogador responsável por mostrar o texto da IA!
+ // Diagnóstico
+ private ProgressBar progressPoupanca;
+ private TextView tvTaxaPoupancaValor, tvReceitasResumo, tvDespesasResumo;
+ private TextView tvTituloDica1, tvDescDica1;
+ private TextView tvTituloDica2, tvDescDica2;
+ private TextView tvTituloDica3, tvDescDica3;
+
+ // Top Despesas
+ private LinearLayout layoutDistribuicao;
private int corFundoCartao;
private int corTextoDinamico;
@@ -61,10 +64,19 @@ public class DicasFragment extends Fragment {
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_dicas, container, false);
- tvTaxaPoupanca = view.findViewById(R.id.tvTaxaPoupanca);
- tvDicasReceitas = view.findViewById(R.id.tvDicasReceitas);
- tvDicasDespesas = view.findViewById(R.id.tvDicasDespesas);
+ if (getContext() != null) {
+ corFundoCartao = ContextCompat.getColor(getContext(), R.color.fundo_cartao);
+ corTextoDinamico = ContextCompat.getColor(getContext(), R.color.texto_principal);
+ }
+
+ editPerguntaAI = view.findViewById(R.id.editPerguntaAI);
+ btnEnviarAI = view.findViewById(R.id.btnEnviarAI);
+ tvRespostaAI = view.findViewById(R.id.tvRespostaAI); // Ligar ao XML
+
progressPoupanca = view.findViewById(R.id.progressPoupanca);
+ tvTaxaPoupancaValor = view.findViewById(R.id.tvTaxaPoupancaValor);
+ tvReceitasResumo = view.findViewById(R.id.tvReceitasResumo);
+ tvDespesasResumo = view.findViewById(R.id.tvDespesasResumo);
tvTituloDica1 = view.findViewById(R.id.tvTituloDica1);
tvDescDica1 = view.findViewById(R.id.tvDescDica1);
@@ -74,30 +86,29 @@ public class DicasFragment extends Fragment {
tvDescDica3 = view.findViewById(R.id.tvDescDica3);
layoutDistribuicao = view.findViewById(R.id.layoutDistribuicao);
- layoutConteudoDicas = view.findViewById(R.id.layoutConteudoDicas);
- layoutEstadoVazioDicas = view.findViewById(R.id.layoutEstadoVazioDicas);
- tvRespostaAI = view.findViewById(R.id.tvRespostaAI);
- editPerguntaAI = view.findViewById(R.id.editPerguntaAI);
- btnEnviarAI = view.findViewById(R.id.btnEnviarAI);
- pbCarregandoAI = view.findViewById(R.id.pbCarregandoAI);
-
- if (getContext() != null) {
- corFundoCartao = ContextCompat.getColor(getContext(), R.color.fundo_cartao);
- corTextoDinamico = ContextCompat.getColor(getContext(), R.color.texto_principal);
+ if (btnEnviarAI != null) {
+ btnEnviarAI.setOnClickListener(v -> perguntarAoNovoCoach());
}
- btnEnviarAI.setOnClickListener(v -> perguntarAoNovoCoach());
-
return view;
}
private void perguntarAoNovoCoach() {
+ if (editPerguntaAI == null || tvRespostaAI == null) return;
+
String pergunta = editPerguntaAI.getText().toString().trim();
if (pergunta.isEmpty()) return;
- pbCarregandoAI.setVisibility(View.VISIBLE);
- tvRespostaAI.setText("A analisar os dados de forma inteligente...");
+ // Tática: Esconder o teclado para não tapar a resposta
+ InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
+ if (imm != null) {
+ imm.hideSoftInputFromWindow(editPerguntaAI.getWindowToken(), 0);
+ }
+
+ // Escrever logo no cartão que a máquina está a pensar!
+ tvRespostaAI.setText("A processar análise... 🧠");
+ tvRespostaAI.setTextColor(ContextCompat.getColor(getContext(), R.color.tech_accent_cyan));
editPerguntaAI.setText("");
OkHttpClient client = new OkHttpClient();
@@ -138,8 +149,8 @@ public class DicasFragment extends Fragment {
public void onFailure(@NonNull Call call, @NonNull IOException e) {
if (getActivity() != null) {
getActivity().runOnUiThread(() -> {
- pbCarregandoAI.setVisibility(View.GONE);
- tvRespostaAI.setText("Erro de ligação ao serviço de Inteligência Artificial.");
+ tvRespostaAI.setText("Falha na ligação. A minha antena está sem sinal, tenta outra vez! 📡");
+ tvRespostaAI.setTextColor(Color.parseColor("#F56565")); // Vermelho suave
});
}
}
@@ -147,25 +158,26 @@ public class DicasFragment extends Fragment {
@Override
public void onResponse(@NonNull Call call, @NonNull Response response) throws IOException {
final String respBody = response.body() != null ? response.body().string() : "";
-
if (getActivity() != null) {
getActivity().runOnUiThread(() -> {
- pbCarregandoAI.setVisibility(View.GONE);
if (response.isSuccessful()) {
try {
JSONObject jsonObject = new JSONObject(respBody);
String respostaIA = jsonObject.getJSONArray("choices")
.getJSONObject(0).getJSONObject("message").getString("content");
- String textoFormatado = respostaIA.replaceAll("\\*\\*(.*?)\\*\\*", "$1");
- textoFormatado = textoFormatado.replace("\n", "
");
- tvRespostaAI.setText(android.text.Html.fromHtml(textoFormatado, android.text.Html.FROM_HTML_MODE_LEGACY));
+ // Limpar asteriscos e colocar a resposta diretamente no cartão!
+ String textoLimpo = respostaIA.replaceAll("\\*\\*", "");
+ tvRespostaAI.setText(textoLimpo);
+ tvRespostaAI.setTextColor(ContextCompat.getColor(getContext(), R.color.text_secondary)); // Volta à cor normal
} catch (Exception e) {
- tvRespostaAI.setText("Erro a ler os dados da análise: " + e.getMessage());
+ tvRespostaAI.setText("Erro ao processar a resposta dos servidores.");
+ tvRespostaAI.setTextColor(Color.parseColor("#F56565"));
}
} else {
- tvRespostaAI.setText("O Assistente não está disponível neste momento.");
+ tvRespostaAI.setText("Os servidores da IA estão ocupados neste momento. ⏱️");
+ tvRespostaAI.setTextColor(Color.parseColor("#ECC94B")); // Amarelo de aviso
}
});
}
@@ -216,9 +228,7 @@ public class DicasFragment extends Fragment {
mapaGastos.put(cat, mapaGastos.getOrDefault(cat, 0f) + v);
}
}
-
buscarOrcamentosECriarCerebro(userId, client, rec, desp, mapaGastos);
-
} catch (Exception e) { e.printStackTrace(); }
}
});
@@ -242,13 +252,11 @@ public class DicasFragment extends Fragment {
String body = response.body().string();
JSONArray arrayOrcamentos = new JSONArray(body);
- // 🧠 RECONSTRUIR O CÉREBRO DA IA COM TODOS OS DETALHES!
StringBuilder cerebro = new StringBuilder();
- cerebro.append("DADOS FINANCEIROS ATUAIS DO UTILIZADOR: ");
- cerebro.append("Receitas Totais: ").append(rec).append("€. ");
- cerebro.append("Despesas Totais: ").append(desp).append("€. ");
+ cerebro.append("DADOS FINANCEIROS ATUAIS: ");
+ cerebro.append("Receitas: ").append(rec).append("€. ");
+ cerebro.append("Despesas: ").append(desp).append("€. ");
- // Passar as categorias onde gastaste dinheiro
if (!mapaGastos.isEmpty()) {
cerebro.append("Gastos por categoria: ");
for (Map.Entry entry : mapaGastos.entrySet()) {
@@ -257,19 +265,16 @@ public class DicasFragment extends Fragment {
}
if (arrayOrcamentos.length() > 0) {
- cerebro.append(". ORÇAMENTOS DEFINIDOS: ");
+ cerebro.append(". ORÇAMENTOS: ");
for (int i = 0; i < arrayOrcamentos.length(); i++) {
JSONObject obj = arrayOrcamentos.getJSONObject(i);
String cat = obj.getString("categoria");
float limite = (float) obj.getDouble("valor_limite");
float gasto = mapaGastos.containsKey(cat) ? mapaGastos.get(cat) : 0f;
- cerebro.append("[").append(cat).append(": Limite definido ").append(limite).append("€, Gasto atual ").append(gasto).append("€] ");
+ cerebro.append("[").append(cat).append(": Limite ").append(limite).append("€, Gasto ").append(gasto).append("€] ");
}
- } else {
- cerebro.append(". O utilizador não tem orçamentos definidos de momento. ");
}
- // ⚠️ A JOGADA QUE FALTAVA: Guardar a memória na variável que a IA vai ler!
contextoFinanceiroParaAI = cerebro.toString();
if (getActivity() != null) {
@@ -282,24 +287,14 @@ public class DicasFragment extends Fragment {
private void aplicarLogicaDeDicas(float rec, float desp, HashMap mapa, JSONArray arrayOrcamentos) {
- if (rec == 0 && desp == 0) {
- layoutConteudoDicas.setVisibility(View.GONE);
- layoutEstadoVazioDicas.setVisibility(View.VISIBLE);
- return;
- } else {
- layoutConteudoDicas.setVisibility(View.VISIBLE);
- layoutEstadoVazioDicas.setVisibility(View.GONE);
- }
-
- // --- TOPO: RESUMO ---
- tvDicasReceitas.setText(String.format("€ %.2f", rec));
- tvDicasDespesas.setText(String.format("€ %.2f", desp));
float taxa = (rec > 0) ? ((rec - desp) / rec) * 100 : 0;
if (taxa < 0) taxa = 0;
- tvTaxaPoupanca.setText(String.format("%.1f%%", taxa));
- progressPoupanca.setProgress((int) taxa);
- // --- CARTÃO 1: REGRA 50/30/20 ---
+ if (progressPoupanca != null) progressPoupanca.setProgress((int) taxa);
+ if (tvTaxaPoupancaValor != null) tvTaxaPoupancaValor.setText(String.format("%.1f%%", taxa));
+ if (tvReceitasResumo != null) tvReceitasResumo.setText(String.format("€ %.2f", rec));
+ if (tvDespesasResumo != null) tvDespesasResumo.setText(String.format("€ %.2f", desp));
+
float necessidades = 0; float desejos = 0;
for (Map.Entry entry : mapa.entrySet()) {
String cat = entry.getKey().toLowerCase();
@@ -316,25 +311,20 @@ public class DicasFragment extends Fragment {
float percDesejos = (desejos / rec) * 100;
if (percNecessidades <= 50 && percDesejos <= 30) {
- tvTituloDica1.setText("Balanço Perfeito ⚖️");
- tvTituloDica1.setTextColor(Color.parseColor("#00E676"));
- tvDescDica1.setText("Estás a cumprir a Regra de Ouro (50/30/20). Os teus gastos essenciais e de lazer estão equilibrados face aos teus rendimentos.");
+ if(tvTituloDica1 != null) { tvTituloDica1.setText("Balanço Perfeito ⚖️"); tvTituloDica1.setTextColor(Color.parseColor("#00E676")); }
+ if(tvDescDica1 != null) tvDescDica1.setText("Estás a cumprir a Regra de Ouro (50/30/20). Os teus gastos essenciais e de lazer estão equilibrados face aos teus rendimentos.");
} else if (percDesejos > 30) {
- tvTituloDica1.setText("Atenção aos Gastos Supérfluos 🛍️");
- tvTituloDica1.setTextColor(Color.parseColor("#ECC94B"));
- tvDescDica1.setText(String.format("A alocação em despesas não essenciais representa %.0f%% do teu orçamento. Recomenda-se reduzir para a margem dos 30%%.", percDesejos));
+ if(tvTituloDica1 != null) { tvTituloDica1.setText("Atenção aos Gastos Supérfluos 🛍️"); tvTituloDica1.setTextColor(Color.parseColor("#ECC94B")); }
+ if(tvDescDica1 != null) tvDescDica1.setText(String.format("A alocação em despesas não essenciais representa %.0f%% do teu orçamento. Recomenda-se reduzir para a margem dos 30%%.", percDesejos));
} else {
- tvTituloDica1.setText("Despesas Fixas Elevadas 🏠");
- tvTituloDica1.setTextColor(Color.parseColor("#F56565"));
- tvDescDica1.setText(String.format("Os teus encargos fixos representam %.0f%% do salário. O indicador ideal para manter a estabilidade financeira é de 50%%.", percNecessidades));
+ if(tvTituloDica1 != null) { tvTituloDica1.setText("Despesas Fixas Elevadas 🏠"); tvTituloDica1.setTextColor(Color.parseColor("#F56565")); }
+ if(tvDescDica1 != null) tvDescDica1.setText(String.format("Os teus encargos fixos representam %.0f%% do salário. O indicador ideal para manter a estabilidade financeira é de 50%%.", percNecessidades));
}
} else {
- tvTituloDica1.setText("Regra 50/30/20 ⚖️");
- tvTituloDica1.setTextColor(corTextoDinamico);
- tvDescDica1.setText("Regista receitas para que possamos calcular a distribuição ideal do teu património.");
+ if(tvTituloDica1 != null) { tvTituloDica1.setText("Regra 50/30/20 ⚖️"); tvTituloDica1.setTextColor(corTextoDinamico); }
+ if(tvDescDica1 != null) tvDescDica1.setText("Regista receitas para que possamos calcular a distribuição ideal do teu património.");
}
- // --- CARTÃO 2: RADAR DE ORÇAMENTOS ---
String alertaOrcamento = "Todos os orçamentos definidos encontram-se dentro dos limites previstos.";
int corAlerta = Color.parseColor("#00E676");
String tituloAlerta = "Orçamentos Controlados ✅";
@@ -363,7 +353,7 @@ public class DicasFragment extends Fragment {
if (maiorRisco >= 1.0) {
tituloAlerta = "Orçamento Excedido 🚨";
corAlerta = Color.parseColor("#FF1744");
- alertaOrcamento = "O limite definido para a categoria '" + catRisco + "' foi ultrapassado. Sugere-se o reajuste das restantes categorias.";
+ alertaOrcamento = "O limite definido para a categoria '" + catRisco + "' foi ultrapassado. Sugere-se o reajuste.";
} else if (maiorRisco >= 0.8) {
tituloAlerta = "Aviso de Limite Próximo ⚠️";
corAlerta = Color.parseColor("#ECC94B");
@@ -375,11 +365,9 @@ public class DicasFragment extends Fragment {
}
} catch (Exception e) { e.printStackTrace(); }
- tvTituloDica2.setText(tituloAlerta);
- tvTituloDica2.setTextColor(corAlerta);
- tvDescDica2.setText(alertaOrcamento);
+ if(tvTituloDica2 != null) { tvTituloDica2.setText(tituloAlerta); tvTituloDica2.setTextColor(corAlerta); }
+ if(tvDescDica2 != null) tvDescDica2.setText(alertaOrcamento);
- // --- CARTÃO 3: PREVISÃO E TENDÊNCIA DIÁRIA ---
Calendar cal = Calendar.getInstance();
int diaAtual = cal.get(Calendar.DAY_OF_MONTH);
int diasNoMes = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
@@ -389,67 +377,65 @@ public class DicasFragment extends Fragment {
float previsaoFimDoMes = mediaDiaria * diasNoMes;
if (previsaoFimDoMes > rec && rec > 0) {
- tvTituloDica3.setText("Projeção Mensal Elevada 📈");
- tvTituloDica3.setTextColor(Color.parseColor("#FF1744"));
- tvDescDica3.setText(String.format("A média de custos diários situa-se em %.2f€. Mantendo esta tendência, o custo final estimado será de %.2f€ (acima dos rendimentos).", mediaDiaria, previsaoFimDoMes));
+ if(tvTituloDica3 != null) { tvTituloDica3.setText("Projeção Mensal Elevada 📈"); tvTituloDica3.setTextColor(Color.parseColor("#FF1744")); }
+ if(tvDescDica3 != null) tvDescDica3.setText(String.format("A média de custos diários situa-se em %.2f€. Mantendo esta tendência, o custo final estimado será de %.2f€ (acima dos rendimentos).", mediaDiaria, previsaoFimDoMes));
} else {
- tvTituloDica3.setText("Projeção Mensal Controlada 📉");
- tvTituloDica3.setTextColor(Color.parseColor("#00E676"));
- tvDescDica3.setText(String.format("A tua média de custos é de %.2f€ diários. A estimativa projetada para o final do mês é de %.2f€.", mediaDiaria, previsaoFimDoMes));
+ if(tvTituloDica3 != null) { tvTituloDica3.setText("Projeção Mensal Controlada 📉"); tvTituloDica3.setTextColor(Color.parseColor("#00E676")); }
+ if(tvDescDica3 != null) tvDescDica3.setText(String.format("A tua média de custos é de %.2f€ diários. A estimativa projetada para o final do mês é de %.2f€.", mediaDiaria, previsaoFimDoMes));
}
} else {
- tvTituloDica3.setText("Projeção de Despesas 📊");
- tvTituloDica3.setTextColor(corTextoDinamico);
- tvDescDica3.setText("Regista mais movimentos ao longo do mês para que o sistema possa projetar a tua média diária de despesas.");
+ if(tvTituloDica3 != null) { tvTituloDica3.setText("Projeção de Despesas 📊"); tvTituloDica3.setTextColor(corTextoDinamico); }
+ if(tvDescDica3 != null) tvDescDica3.setText("Regista mais movimentos ao longo do mês para projetarmos a tua média diária.");
}
- // --- LISTA DE TOP DESPESAS ---
- layoutDistribuicao.removeAllViews();
- for (Map.Entry entry : mapa.entrySet()) {
- String categoria = entry.getKey();
- float valor = entry.getValue();
+ if (layoutDistribuicao != null) {
+ layoutDistribuicao.removeAllViews();
+ for (Map.Entry entry : mapa.entrySet()) {
+ String categoria = entry.getKey();
+ float valor = entry.getValue();
- LinearLayout row = new LinearLayout(getContext());
- row.setOrientation(LinearLayout.HORIZONTAL);
- row.setPadding(40, 30, 40, 30);
- row.setElevation(2f);
+ LinearLayout row = new LinearLayout(getContext());
+ row.setOrientation(LinearLayout.HORIZONTAL);
+ row.setPadding(40, 40, 40, 40);
+ row.setElevation(0f);
- GradientDrawable shape = new GradientDrawable();
- shape.setCornerRadius(24f);
- shape.setColor(corFundoCartao);
- row.setBackground(shape);
+ GradientDrawable shape = new GradientDrawable();
+ shape.setCornerRadius(32f);
+ shape.setColor(corFundoCartao);
+ row.setBackground(shape);
- LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
- LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
- params.setMargins(0, 0, 0, 20);
- row.setLayoutParams(params);
+ LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
+ LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
+ params.setMargins(0, 0, 0, 24);
+ row.setLayoutParams(params);
- String emoji = "💰";
- String catLower = categoria.toLowerCase();
- if (catLower.contains("alimen") || catLower.contains("restaurante")) emoji = "🍔";
- else if (catLower.contains("transp") || catLower.contains("carro")) emoji = "🚗";
- else if (catLower.contains("lazer") || catLower.contains("divers")) emoji = "🎮";
- else if (catLower.contains("saúd") || catLower.contains("farmácia")) emoji = "💊";
- else if (catLower.contains("educa")) emoji = "📚";
- else if (catLower.contains("casa") || catLower.contains("renda") || catLower.contains("conta")) emoji = "🏠";
- else if (catLower.contains("compras") || catLower.contains("roupa")) emoji = "🛍️";
+ String emoji = "💰";
+ String catLower = categoria.toLowerCase();
+ if (catLower.contains("alimen") || catLower.contains("restaurante")) emoji = "🍔";
+ else if (catLower.contains("transp") || catLower.contains("carro")) emoji = "🚗";
+ else if (catLower.contains("lazer") || catLower.contains("divers")) emoji = "🎮";
+ else if (catLower.contains("saúd") || catLower.contains("farmácia")) emoji = "💊";
+ else if (catLower.contains("educa")) emoji = "📚";
+ else if (catLower.contains("casa") || catLower.contains("renda") || catLower.contains("conta")) emoji = "🏠";
+ else if (catLower.contains("compras") || catLower.contains("roupa")) emoji = "🛍️";
- TextView tvCat = new TextView(getContext());
- tvCat.setText(emoji + " " + categoria);
- tvCat.setTextColor(corTextoDinamico);
- tvCat.setTextSize(16f);
- tvCat.setTypeface(null, Typeface.BOLD);
- tvCat.setLayoutParams(new LinearLayout.LayoutParams(0, ViewGroup.LayoutParams.WRAP_CONTENT, 1f));
+ TextView tvCat = new TextView(getContext());
+ tvCat.setText(emoji + " " + categoria);
+ tvCat.setTextColor(corTextoDinamico);
+ tvCat.setTextSize(16f);
+ tvCat.setTypeface(null, Typeface.BOLD);
+ tvCat.setLayoutParams(new LinearLayout.LayoutParams(0, ViewGroup.LayoutParams.WRAP_CONTENT, 1f));
- TextView tvVal = new TextView(getContext());
- tvVal.setText(String.format("€ %.2f", valor));
- tvVal.setTextColor(Color.parseColor("#FF1744"));
- tvVal.setTextSize(16f);
- tvVal.setTypeface(null, Typeface.BOLD);
+ TextView tvVal = new TextView(getContext());
+ tvVal.setText(String.format("€ %.2f", valor));
+ tvVal.setTextColor(Color.parseColor("#FF1744"));
+ tvVal.setTextSize(16f);
+ tvVal.setTypeface(null, Typeface.BOLD);
- row.addView(tvCat);
- row.addView(tvVal);
- layoutDistribuicao.addView(row);
+ row.addView(tvCat);
+ row.addView(tvVal);
+ layoutDistribuicao.addView(row);
+ }
}
}
}
\ No newline at end of file
diff --git a/app/src/main/java/com/example/finzora/EditarPerfilActivity.java b/app/src/main/java/com/example/finzora/EditarPerfilActivity.java
index 7579100..f4a4488 100644
--- a/app/src/main/java/com/example/finzora/EditarPerfilActivity.java
+++ b/app/src/main/java/com/example/finzora/EditarPerfilActivity.java
@@ -28,6 +28,7 @@ public class EditarPerfilActivity extends AppCompatActivity {
private EditText editNomePerfil;
private EditText editEmailPerfil;
+ private EditText editTelemovelPerfil; // NOVO JOGADOR INSCRITO!
private ImageView imgFotoPerfil;
private String caminhoFotoGuardada = null;
@@ -56,18 +57,23 @@ public class EditarPerfilActivity extends AppCompatActivity {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_editar_perfil);
- TextView btnVoltar = findViewById(R.id.btnVoltarEditarPerfil);
+ // A CORREÇÃO DE MESTRE: Agora a seta de voltar é lida como ImageView (Imagem)
+ ImageView btnVoltar = findViewById(R.id.btnVoltarEditarPerfil);
editNomePerfil = findViewById(R.id.editNomePerfil);
editEmailPerfil = findViewById(R.id.editEmailPerfil);
+ editTelemovelPerfil = findViewById(R.id.editTelemovelPerfil); // Ligar ao XML
+ Button btnAlterarPassword = findViewById(R.id.btnAlterarPassword); // Ligar ao XML
Button btnGuardarPerfil = findViewById(R.id.btnGuardarPerfil);
imgFotoPerfil = findViewById(R.id.imgFotoPerfil);
btnVoltar.setOnClickListener(v -> finish());
imgFotoPerfil.setOnClickListener(v -> seletorImagens.launch("image/*"));
+ // Carregar os dados que já estavam guardados na app
SharedPreferences prefs = getSharedPreferences("DadosUtilizador", MODE_PRIVATE);
editNomePerfil.setText(prefs.getString("nome_usuario", "Investidor"));
editEmailPerfil.setText(prefs.getString("email_usuario", ""));
+ editTelemovelPerfil.setText(prefs.getString("telemovel_usuario", "")); // Carrega o telemóvel
caminhoFotoGuardada = prefs.getString("foto_usuario_path", null);
if (caminhoFotoGuardada != null) {
@@ -85,9 +91,16 @@ public class EditarPerfilActivity extends AppCompatActivity {
}
}
+ // 🚀 PASSE DE RUTURA: Abrir o novo ecrã profissional de segurança
+ btnAlterarPassword.setOnClickListener(v -> {
+ startActivity(new Intent(EditarPerfilActivity.this, AlterarPasswordActivity.class));
+ });
+
+ // Quando o utilizador clica em Guardar
btnGuardarPerfil.setOnClickListener(v -> {
String novoNome = editNomePerfil.getText().toString().trim();
String novoEmail = editEmailPerfil.getText().toString().trim();
+ String novoTelemovel = editTelemovelPerfil.getText().toString().trim(); // Lê o que foi escrito
if (novoNome.isEmpty()) {
editNomePerfil.setError("O nome não pode estar vazio!");
@@ -97,6 +110,7 @@ public class EditarPerfilActivity extends AppCompatActivity {
SharedPreferences.Editor editor = prefs.edit();
editor.putString("nome_usuario", novoNome);
editor.putString("email_usuario", novoEmail);
+ editor.putString("telemovel_usuario", novoTelemovel); // Guarda o telemóvel
if (caminhoFotoGuardada != null) {
editor.putString("foto_usuario_path", caminhoFotoGuardada);
diff --git a/app/src/main/java/com/example/finzora/GraficosFragment.java b/app/src/main/java/com/example/finzora/GraficosFragment.java
index bd18614..8041af7 100644
--- a/app/src/main/java/com/example/finzora/GraficosFragment.java
+++ b/app/src/main/java/com/example/finzora/GraficosFragment.java
@@ -42,11 +42,11 @@ public class GraficosFragment extends Fragment {
private BarChart barChartOrcamento;
private BarChart barChartTendencia;
- // ⚠️ 1. As Vistas do Estado Vazio
private View scrollviewGraficos;
private View layoutEstadoVazio;
private int corTextoDinamica;
+ private int corGridSubtil;
@Nullable
@Override
@@ -57,14 +57,15 @@ public class GraficosFragment extends Fragment {
barChartOrcamento = view.findViewById(R.id.barChartOrcamento);
barChartTendencia = view.findViewById(R.id.barChartTendencia);
- // ⚠️ 2. Ligar ao XML
scrollviewGraficos = view.findViewById(R.id.scrollviewGraficos);
layoutEstadoVazio = view.findViewById(R.id.layoutEstadoVazioGraficos);
if (getContext() != null) {
corTextoDinamica = ContextCompat.getColor(getContext(), R.color.texto_principal);
+ corGridSubtil = Color.parseColor("#1A888888"); // Uma grelha muito subtil e quase invisível
} else {
corTextoDinamica = Color.BLACK;
+ corGridSubtil = Color.LTGRAY;
}
return view;
@@ -125,18 +126,14 @@ public class GraficosFragment extends Fragment {
final float totalDespesas = somaDespesas;
final Map mapaGastos = gastosPorCategoria;
- // ⚠️ 3. A Lógica de Mostrar/Esconder
if (getActivity() != null) {
getActivity().runOnUiThread(() -> {
- // Se as receitas E as despesas forem 0, é porque não há transações nenhumas!
if (totalReceitas == 0 && totalDespesas == 0) {
scrollviewGraficos.setVisibility(View.GONE);
layoutEstadoVazio.setVisibility(View.VISIBLE);
} else {
scrollviewGraficos.setVisibility(View.VISIBLE);
layoutEstadoVazio.setVisibility(View.GONE);
-
- // O utilizador tem dados! Vamos buscar os orçamentos para cruzar a informação
carregarOrcamentosEDesenhar(userId, mapaGastos, totalReceitas, totalDespesas);
}
});
@@ -193,6 +190,7 @@ public class GraficosFragment extends Fragment {
pieChartDespesas.getLegend().setTextColor(corTextoDinamica);
pieChartDespesas.getLegend().setTextSize(12f);
pieChartDespesas.getLegend().setWordWrapEnabled(true);
+ pieChartDespesas.getLegend().setForm(com.github.mikephil.charting.components.Legend.LegendForm.CIRCLE); // Fica mais tecnológico!
pieChartDespesas.setCenterText("Despesas");
pieChartDespesas.setCenterTextColor(corTextoDinamica);
@@ -208,14 +206,24 @@ public class GraficosFragment extends Fragment {
if (entradas.isEmpty()) { pieChartDespesas.clear(); return; }
PieDataSet dataSet = new PieDataSet(entradas, "");
- dataSet.setColors(new int[]{Color.parseColor("#7C4DFF"), Color.parseColor("#00E5FF"), Color.parseColor("#FFD600"), Color.parseColor("#FF4081")});
- dataSet.setSliceSpace(3f);
+
+ // 🚀 PALETA CYBERPUNK PREMIUM: Tons Ciano, Azul Escuro, Roxo Neon, etc.
+ dataSet.setColors(new int[]{
+ Color.parseColor("#00E5FF"), // Cyan Tech
+ Color.parseColor("#2979FF"), // Blue Deep
+ Color.parseColor("#D500F9"), // Neon Purple
+ Color.parseColor("#00E676"), // Emerald
+ Color.parseColor("#FFEA00"), // Yellow Tech
+ Color.parseColor("#FF1744") // Danger Red
+ });
+
+ dataSet.setSliceSpace(4f); // Espaço entre as fatias dá o efeito premium
PieData data = new PieData(dataSet);
- data.setValueTextSize(14f);
- data.setValueTextColor(corTextoDinamica);
+ data.setValueTextSize(12f);
+ data.setValueTextColor(Color.WHITE); // Branco destaca bem em cima destas cores fortes
pieChartDespesas.setData(data);
- pieChartDespesas.animateY(1000);
+ pieChartDespesas.animateY(1200);
}
private void desenharBarChartOrcamento(Map orcamentos, Map gastos) {
@@ -239,17 +247,16 @@ public class GraficosFragment extends Fragment {
if (categorias.isEmpty()) { barChartOrcamento.clear(); return; }
- BarDataSet setGastos = new BarDataSet(gastosEntries, "Gastos Reais");
- setGastos.setColor(Color.parseColor("#FF4081"));
+ BarDataSet setGastos = new BarDataSet(gastosEntries, "Gasto Real");
+ setGastos.setColor(Color.parseColor("#FF1744")); // Vermelho de Gasto
setGastos.setValueTextColor(corTextoDinamica);
- BarDataSet setOrcamento = new BarDataSet(orcamentoEntries, "Orçamento");
- setOrcamento.setColor(Color.parseColor("#00E5FF"));
+ BarDataSet setOrcamento = new BarDataSet(orcamentoEntries, "Limite (Orçamento)");
+ setOrcamento.setColor(Color.parseColor("#00B8D4")); // Ciano Tech do Limite
setOrcamento.setValueTextColor(corTextoDinamica);
BarData data = new BarData(setGastos, setOrcamento);
- // ⚠️ A MATEMÁTICA PERFEITA (tem de somar 1.00)
float barWidth = 0.35f;
float barSpace = 0.05f;
float groupSpace = 0.20f;
@@ -257,21 +264,16 @@ public class GraficosFragment extends Fragment {
data.setBarWidth(barWidth);
barChartOrcamento.setData(data);
- // ⚠️ COMEÇA NO 0 PARA ALINHAR AO CENTRO
barChartOrcamento.groupBars(0f, groupSpace, barSpace);
XAxis xAxis = barChartOrcamento.getXAxis();
xAxis.setValueFormatter(new IndexAxisValueFormatter(categorias));
-
- // ⚠️ LIMITES DINÂMICOS PARA ENCAIXAR OS GRUPOS TODOS
xAxis.setAxisMinimum(0f);
xAxis.setAxisMaximum(barChartOrcamento.getBarData().getGroupWidth(groupSpace, barSpace) * categorias.size());
- // Para não ficar tudo esmagado se tiveres muitas categorias, mete limite visível a 4
barChartOrcamento.setVisibleXRangeMaximum(4);
-
- barChartOrcamento.animateY(1000);
- barChartOrcamento.invalidate(); // Refresca o gráfico
+ barChartOrcamento.animateY(1200);
+ barChartOrcamento.invalidate();
}
private void desenharBarChartTendencia(float receitas, float despesas) {
@@ -284,16 +286,15 @@ public class GraficosFragment extends Fragment {
receitaEntry.add(new BarEntry(0, receitas));
BarDataSet setDespesas = new BarDataSet(despesaEntry, "Despesas");
- setDespesas.setColor(Color.parseColor("#FF1744"));
+ setDespesas.setColor(Color.parseColor("#FF1744")); // Red Tech
setDespesas.setValueTextColor(corTextoDinamica);
BarDataSet setReceitas = new BarDataSet(receitaEntry, "Receitas");
- setReceitas.setColor(Color.parseColor("#00E676"));
+ setReceitas.setColor(Color.parseColor("#00E676")); // Green Emerald
setReceitas.setValueTextColor(corTextoDinamica);
BarData data = new BarData(setDespesas, setReceitas);
- // ⚠️ MATEMÁTICA PERFEITA PARA A TENDÊNCIA
float groupSpace = 0.3f;
float barSpace = 0.05f;
float barWidth = 0.3f;
@@ -301,36 +302,39 @@ public class GraficosFragment extends Fragment {
data.setBarWidth(barWidth);
barChartTendencia.setData(data);
- // ⚠️ COMEÇA NO 0 TAMBÉM
barChartTendencia.groupBars(0f, groupSpace, barSpace);
ArrayList labelMes = new ArrayList<>();
- labelMes.add("Atual");
+ labelMes.add("Mês Atual");
XAxis xAxis = barChartTendencia.getXAxis();
xAxis.setValueFormatter(new IndexAxisValueFormatter(labelMes));
- // ⚠️ COMO É SÓ 1 GRUPO, O MÁXIMO É 1
xAxis.setAxisMinimum(0f);
xAxis.setAxisMaximum(1f);
- barChartTendencia.animateY(1000);
+ barChartTendencia.animateY(1200);
barChartTendencia.invalidate();
}
private void configurarEstiloBarChart(BarChart chart) {
chart.getDescription().setEnabled(false);
+
chart.getLegend().setTextColor(corTextoDinamica);
- chart.getAxisRight().setEnabled(false);
+ chart.getLegend().setForm(com.github.mikephil.charting.components.Legend.LegendForm.CIRCLE); // Ícones redondos na legenda
+
+ chart.getAxisRight().setEnabled(false); // Desliga eixo direito
chart.getAxisLeft().setTextColor(corTextoDinamica);
chart.getAxisLeft().setDrawGridLines(true);
- chart.getAxisLeft().setGridColor(Color.LTGRAY);
+ chart.getAxisLeft().setGridColor(corGridSubtil); // Grelha muito subtil e tecnológica
+ chart.getAxisLeft().setAxisLineColor(Color.TRANSPARENT); // Remove linha forte do eixo Y
XAxis xAxis = chart.getXAxis();
xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);
xAxis.setTextColor(corTextoDinamica);
- xAxis.setDrawGridLines(false);
+ xAxis.setDrawGridLines(false); // Remove grelha feia vertical
+ xAxis.setAxisLineColor(corGridSubtil);
xAxis.setGranularity(1f);
xAxis.setCenterAxisLabels(true);
}
diff --git a/app/src/main/java/com/example/finzora/MainActivity.java b/app/src/main/java/com/example/finzora/MainActivity.java
index 9e3e313..90cca70 100644
--- a/app/src/main/java/com/example/finzora/MainActivity.java
+++ b/app/src/main/java/com/example/finzora/MainActivity.java
@@ -13,7 +13,6 @@ import android.os.Bundle;
import android.os.Environment;
import android.view.LayoutInflater;
import android.view.View;
-import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
@@ -52,7 +51,6 @@ public class MainActivity extends AppCompatActivity {
private ViewPager2 viewPager;
private FloatingActionButton fabAdicionar;
private TextView tvNomeUsuario;
- private Button btnSair;
private TextView tvSaldoGeral, tvReceitasGeral, tvDespesasGeral;
private JSONArray listaTransacoesGlobal;
@@ -76,7 +74,6 @@ public class MainActivity extends AppCompatActivity {
viewPager = findViewById(R.id.viewPager);
fabAdicionar = findViewById(R.id.fabAdicionar);
tvNomeUsuario = findViewById(R.id.tvNomeUsuario);
- btnSair = findViewById(R.id.btnSair);
tvSaldoGeral = findViewById(R.id.tvSaldoGeral);
tvReceitasGeral = findViewById(R.id.tvReceitasGeral);
@@ -86,8 +83,6 @@ public class MainActivity extends AppCompatActivity {
String nome = prefs.getString("nome_usuario", "Investidor");
tvNomeUsuario.setText("Olá, " + nome);
- btnSair.setOnClickListener(v -> finishAffinity());
-
fabAdicionar.setOnClickListener(v -> startActivity(new Intent(this, AdicionarTransacaoActivity.class)));
ImageView btnAbrirDefinicoes = findViewById(R.id.btnAbrirDefinicoes);
diff --git a/app/src/main/res/drawable/ic_bell.xml b/app/src/main/res/drawable/ic_bell.xml
new file mode 100644
index 0000000..a7d48df
--- /dev/null
+++ b/app/src/main/res/drawable/ic_bell.xml
@@ -0,0 +1,10 @@
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/ic_chevron_right.xml b/app/src/main/res/drawable/ic_chevron_right.xml
new file mode 100644
index 0000000..faa95a6
--- /dev/null
+++ b/app/src/main/res/drawable/ic_chevron_right.xml
@@ -0,0 +1,10 @@
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/ic_delete_forever.xml b/app/src/main/res/drawable/ic_delete_forever.xml
new file mode 100644
index 0000000..f666063
--- /dev/null
+++ b/app/src/main/res/drawable/ic_delete_forever.xml
@@ -0,0 +1,10 @@
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/ic_edit_profile.xml b/app/src/main/res/drawable/ic_edit_profile.xml
new file mode 100644
index 0000000..7e73f3e
--- /dev/null
+++ b/app/src/main/res/drawable/ic_edit_profile.xml
@@ -0,0 +1,10 @@
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/ic_fingerprint.xml b/app/src/main/res/drawable/ic_fingerprint.xml
new file mode 100644
index 0000000..cecdb83
--- /dev/null
+++ b/app/src/main/res/drawable/ic_fingerprint.xml
@@ -0,0 +1,10 @@
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/ic_lock.xml b/app/src/main/res/drawable/ic_lock.xml
new file mode 100644
index 0000000..3ac42d8
--- /dev/null
+++ b/app/src/main/res/drawable/ic_lock.xml
@@ -0,0 +1,10 @@
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/ic_logout.xml b/app/src/main/res/drawable/ic_logout.xml
new file mode 100644
index 0000000..23d0cb0
--- /dev/null
+++ b/app/src/main/res/drawable/ic_logout.xml
@@ -0,0 +1,10 @@
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/ic_moon.xml b/app/src/main/res/drawable/ic_moon.xml
new file mode 100644
index 0000000..9615267
--- /dev/null
+++ b/app/src/main/res/drawable/ic_moon.xml
@@ -0,0 +1,10 @@
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/ic_support.xml b/app/src/main/res/drawable/ic_support.xml
new file mode 100644
index 0000000..95b3824
--- /dev/null
+++ b/app/src/main/res/drawable/ic_support.xml
@@ -0,0 +1,10 @@
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_alterar_password.xml b/app/src/main/res/layout/activity_alterar_password.xml
new file mode 100644
index 0000000..6da97e3
--- /dev/null
+++ b/app/src/main/res/layout/activity_alterar_password.xml
@@ -0,0 +1,153 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_definicoes.xml b/app/src/main/res/layout/activity_definicoes.xml
index 91b774a..2fb748b 100644
--- a/app/src/main/res/layout/activity_definicoes.xml
+++ b/app/src/main/res/layout/activity_definicoes.xml
@@ -1,117 +1,352 @@
-
+ android:background="@color/fundo_app"
+ tools:context=".DefinicoesActivity">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ android:background="@color/fundo_app"
+ android:orientation="vertical"
+ android:paddingHorizontal="20dp"
+ android:paddingTop="8dp"
+ android:paddingBottom="16dp"
+ app:layout_constraintBottom_toBottomOf="parent">
-
+
+
+ app:cornerRadius="16dp"
+ app:icon="@drawable/ic_logout"
+ app:iconGravity="textStart"
+ app:iconTint="@color/texto_principal"
+ app:strokeColor="@color/linha_separadora"
+ app:strokeWidth="1dp" />
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_editar_perfil.xml b/app/src/main/res/layout/activity_editar_perfil.xml
index 8bcc4c6..d9042d8 100644
--- a/app/src/main/res/layout/activity_editar_perfil.xml
+++ b/app/src/main/res/layout/activity_editar_perfil.xml
@@ -1,96 +1,177 @@
-
+ android:background="@color/fundo_app"
+ android:fillViewport="true">
+ android:orientation="vertical"
+ android:padding="24dp">
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ android:layout_marginBottom="12dp"/>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ android:textSize="16sp"
+ android:textStyle="bold"
+ app:cornerRadius="16dp"
+ app:backgroundTint="@color/tech_accent_cyan" />
+
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml
index c5e0ac0..d581e98 100644
--- a/app/src/main/res/layout/activity_main.xml
+++ b/app/src/main/res/layout/activity_main.xml
@@ -11,38 +11,40 @@
android:layout_height="match_parent"
android:orientation="vertical">
-
+ android:orientation="horizontal"
+ android:gravity="center_vertical"
+ android:paddingHorizontal="24dp"
+ android:paddingTop="32dp"
+ android:paddingBottom="24dp">
+ app:tint="#1A202C" />
+ android:layout_marginStart="16dp">
+ android:textSize="12sp"
+ android:textStyle="bold"
+ android:letterSpacing="0.1"/>
+ android:textSize="22sp"
+ android:textStyle="bold"/>
-
-
-
-
+
+
+
+ android:paddingStart="24dp"
+ android:paddingEnd="24dp"
+ android:clipToPadding="false"
+ android:scrollbars="none">
-
-
+ app:tabIndicatorHeight="3dp"
+ app:tabIndicatorFullWidth="false"
+ app:tabGravity="fill"
+ app:tabMode="scrollable"/>
+ app:tint="#1A202C"
+ app:elevation="4dp"
+ app:fabSize="normal"
+ android:contentDescription="Adicionar Transação"/>
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_dicas.xml b/app/src/main/res/layout/fragment_dicas.xml
index 0fae662..3469bc0 100644
--- a/app/src/main/res/layout/fragment_dicas.xml
+++ b/app/src/main/res/layout/fragment_dicas.xml
@@ -1,313 +1,324 @@
-
+ android:background="@color/fundo_app"
+ android:fillViewport="true">
+ android:padding="20dp">
+ android:text="Conselheiro Inteligente"
+ android:textAllCaps="true"
+ android:textColor="@color/text_secondary"
+ android:textSize="12sp"
+ android:textStyle="bold"
+ android:layout_marginBottom="12dp"/>
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+ app:cardBackgroundColor="@color/fundo_cartao"
+ app:cardCornerRadius="16dp"
+ app:cardElevation="0dp"
+ app:strokeColor="@color/tech_accent_cyan"
+ app:strokeWidth="1dp"
+ android:layout_marginBottom="24dp">
+ android:orientation="vertical"
+ android:padding="16dp">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
\ No newline at end of file
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_graficos.xml b/app/src/main/res/layout/fragment_graficos.xml
index 2556d29..8eba85b 100644
--- a/app/src/main/res/layout/fragment_graficos.xml
+++ b/app/src/main/res/layout/fragment_graficos.xml
@@ -3,111 +3,170 @@
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:background="@color/bg_dinamico">
+ android:background="@color/fundo_app">
-
+ android:layout_height="match_parent"
+ android:fillViewport="true">
+ android:padding="20dp">
-
+
+
+ app:cardCornerRadius="20dp"
+ app:cardElevation="0dp"
+ app:strokeColor="@color/linha_separadora"
+ app:strokeWidth="1dp">
+ android:padding="20dp">
-
+ android:orientation="horizontal"
+ android:gravity="center_vertical"
+ android:layout_marginBottom="24dp">
+
+
+
+
+
-
+
-
+ app:cardCornerRadius="20dp"
+ app:cardElevation="0dp"
+ app:strokeColor="@color/linha_separadora"
+ app:strokeWidth="1dp">
+ android:padding="20dp">
-
+ android:orientation="horizontal"
+ android:gravity="center_vertical"
+ android:layout_marginBottom="24dp">
+
+
+
+
+
+ android:layout_height="280dp"/>
-
+
-
+ app:cardCornerRadius="20dp"
+ app:cardElevation="0dp"
+ app:strokeColor="@color/linha_separadora"
+ app:strokeWidth="1dp">
+ android:padding="20dp">
-
+ android:orientation="horizontal"
+ android:gravity="center_vertical"
+ android:layout_marginBottom="24dp">
+
+
+
+
+
+ android:layout_height="250dp"/>
-
+
-
+
+ android:padding="40dp">
-
+
+ android:layout_marginBottom="8dp"/>
+ android:textColor="@color/text_secondary"/>
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_objetivos.xml b/app/src/main/res/layout/fragment_objetivos.xml
index 78abc31..c513f09 100644
--- a/app/src/main/res/layout/fragment_objetivos.xml
+++ b/app/src/main/res/layout/fragment_objetivos.xml
@@ -3,18 +3,17 @@
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:background="@color/bg_dinamico">
+ android:background="@color/fundo_app">
-
+ android:paddingBottom="100dp"/>
-
+ android:visibility="gone"
+ android:padding="32dp">
+ app:tint="@color/text_secondary"
+ android:layout_marginBottom="16dp"
+ android:alpha="0.4"/>
+
+
-
+ app:tint="#1A202C"
+ app:backgroundTint="@color/tech_accent_cyan"
+ app:elevation="4dp"/>
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_orcamento.xml b/app/src/main/res/layout/fragment_orcamento.xml
index 2a6424f..aed5a5d 100644
--- a/app/src/main/res/layout/fragment_orcamento.xml
+++ b/app/src/main/res/layout/fragment_orcamento.xml
@@ -4,31 +4,34 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
- android:background="?android:attr/windowBackground"
- android:padding="16dp">
+ android:background="@color/fundo_app"
+ android:padding="20dp">
-
+ app:cardBackgroundColor="@color/fundo_cartao"
+ app:cardCornerRadius="20dp"
+ app:cardElevation="0dp"
+ app:strokeColor="@color/linha_separadora"
+ app:strokeWidth="1dp"
+ android:layout_marginBottom="24dp">
+ android:padding="20dp">
+ android:layout_marginEnd="12dp">
+ android:layout_marginBottom="8dp"/>
+ android:paddingHorizontal="16dp"
+ android:background="@drawable/bg_search_bar" />
+ android:orientation="vertical">
+ android:layout_marginBottom="8dp"/>
-
+ android:layout_height="50dp"
+ android:background="@drawable/bg_search_bar"
+ android:gravity="center_vertical"
+ android:paddingHorizontal="12dp">
+
+
+
-
-
+
+ android:layout_marginBottom="12dp"/>
+ android:layout_height="match_parent"
+ android:clipToPadding="false"
+ android:paddingBottom="80dp"/>
+ android:padding="32dp">
-
+
+ android:textColor="@color/texto_principal"
+ android:layout_marginBottom="8dp"/>
+ android:textColor="@color/text_secondary"/>
-
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_transacoes.xml b/app/src/main/res/layout/fragment_transacoes.xml
index 1847d1f..786ea96 100644
--- a/app/src/main/res/layout/fragment_transacoes.xml
+++ b/app/src/main/res/layout/fragment_transacoes.xml
@@ -4,38 +4,45 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
- android:background="@color/bg_dinamico">
+ android:background="@color/fundo_app">
-
+ app:cardBackgroundColor="@color/fundo_cartao"
+ app:cardCornerRadius="12dp"
+ app:cardElevation="0dp">
-
-
-
-
+ android:orientation="horizontal"
+ android:padding="12dp"
+ android:gravity="center_vertical">
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/item_objetivo.xml b/app/src/main/res/layout/item_objetivo.xml
index 57ed497..72f51fa 100644
--- a/app/src/main/res/layout/item_objetivo.xml
+++ b/app/src/main/res/layout/item_objetivo.xml
@@ -1,15 +1,17 @@
-
+ android:layout_marginBottom="12dp"
+ app:cardCornerRadius="20dp"
+ app:cardElevation="0dp"
+ app:strokeColor="@color/linha_separadora"
+ app:strokeWidth="1dp"
+ app:cardBackgroundColor="@color/fundo_cartao">
-
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ android:gravity="center_vertical">
+ android:padding="8dp"
+ app:tint="@color/tech_accent_cyan" />
-
-
+ app:tint="@color/text_secondary" />
-
+ app:tint="@color/text_secondary" />
-
+
+ android:textColor="@color/text_secondary"
+ android:textSize="13sp"
+ android:fontFamily="sans-serif-medium"
+ android:letterSpacing="0.02"/>
@@ -92,20 +94,22 @@
android:id="@+id/progressObjetivo"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="0dp"
- android:layout_height="8dp"
+ android:layout_height="6dp"
android:layout_weight="1"
android:max="100"
android:progress="0"
- android:progressTint="#00B8D4" />
+ android:progressTint="@color/tech_accent_cyan"
+ android:progressBackgroundTint="@color/linha_separadora" />
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/item_orcamento.xml b/app/src/main/res/layout/item_orcamento.xml
index c1cbc67..69efef4 100644
--- a/app/src/main/res/layout/item_orcamento.xml
+++ b/app/src/main/res/layout/item_orcamento.xml
@@ -1,19 +1,20 @@
-
+ android:layout_marginBottom="12dp"
+ app:cardBackgroundColor="@color/fundo_cartao"
+ app:cardCornerRadius="20dp"
+ app:cardElevation="0dp"
+ app:strokeColor="@color/linha_separadora"
+ app:strokeWidth="1dp">
+ android:padding="20dp">
@@ -33,20 +36,21 @@
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
- android:layout_marginStart="12dp"
+ android:layout_marginStart="16dp"
android:text="Alimentação"
- android:textColor="?android:attr/textColorPrimary"
- android:textSize="18sp"
+ android:textColor="@color/texto_principal"
+ android:textSize="16sp"
android:textStyle="bold" />
+ app:tint="@color/text_secondary" />
@@ -61,19 +66,22 @@
android:id="@+id/progressOrcamento"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
- android:layout_height="8dp"
+ android:layout_height="6dp"
android:layout_marginTop="16dp"
android:layout_marginBottom="8dp"
android:progress="75"
- android:progressDrawable="@drawable/custom_progress_bar" />
+ android:progressTint="@color/tech_accent_cyan"
+ android:progressBackgroundTint="@color/linha_separadora" />
-
\ No newline at end of file
+
\ No newline at end of file