This commit is contained in:
2026-04-23 10:40:31 +01:00
parent a74f0e4260
commit 7a4bf84d42
9 changed files with 615 additions and 7 deletions

View File

@@ -1,5 +1,9 @@
package com.example.lifegrid.menu;
import android.app.AlertDialog;
import android.app.DatePickerDialog;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
import androidx.fragment.app.Fragment;
@@ -7,8 +11,21 @@ import androidx.fragment.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.Spinner;
import android.widget.Toast;
import java.util.Calendar;
import java.util.Locale;
import com.example.lifegrid.R;
import com.example.lifegrid.models.Ativos;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
/**
* AtivosFragment diz respeito à janela do ecossistema dedicada à gestão
@@ -31,7 +48,74 @@ public class AtivosFragment extends Fragment {
// Inflaciona o layout para este fragmento
View root = inflater.inflate(R.layout.fragment_ativos, container, false);
Button novaTransacaoButton = root.findViewById(R.id.novaTransacaoButton);
novaTransacaoButton.setOnClickListener(v -> showNovoAtivoDialog());
return root;
}
private void showNovoAtivoDialog() {
AlertDialog.Builder builder = new AlertDialog.Builder(requireContext());
View dialogView = getLayoutInflater().inflate(R.layout.dialog_novo_ativo, null);
builder.setView(dialogView);
AlertDialog dialog = builder.create();
if (dialog.getWindow() != null) {
dialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
}
ImageView btnFechar = dialogView.findViewById(R.id.btnFechar);
btnFechar.setOnClickListener(v -> dialog.dismiss());
EditText etDataCompra = dialogView.findViewById(R.id.etDataCompra);
etDataCompra.setOnClickListener(v -> {
Calendar calendar = Calendar.getInstance();
int year = calendar.get(Calendar.YEAR);
int month = calendar.get(Calendar.MONTH);
int day = calendar.get(Calendar.DAY_OF_MONTH);
DatePickerDialog datePickerDialog = new DatePickerDialog(requireContext(),
(view, selectedYear, selectedMonth, selectedDay) -> {
String formattedDate = String.format(Locale.getDefault(), "%02d/%02d/%04d", selectedDay, selectedMonth + 1, selectedYear);
etDataCompra.setText(formattedDate);
}, year, month, day);
datePickerDialog.show();
});
Button btnAdicionarAtivoDialog = dialogView.findViewById(R.id.btnAdicionarAtivoDialog);
EditText etNomeAtivo = dialogView.findViewById(R.id.etNomeAtivo);
Spinner spinnerTipoAtivo = dialogView.findViewById(R.id.spinnerTipoAtivo);
EditText etQuantidade = dialogView.findViewById(R.id.etQuantidade);
EditText etPrecoCompra = dialogView.findViewById(R.id.etPrecoCompra);
EditText etPrecoAtual = dialogView.findViewById(R.id.etPrecoAtual);
btnAdicionarAtivoDialog.setOnClickListener(v -> {
String nome = etNomeAtivo.getText().toString().trim();
String tipo = spinnerTipoAtivo.getSelectedItem().toString();
String quantidade = etQuantidade.getText().toString().trim();
String precoCompra = etPrecoCompra.getText().toString().trim();
String precoAtual = etPrecoAtual.getText().toString().trim();
String dataCompra = etDataCompra.getText().toString().trim();
Ativos ativos = new Ativos(nome, quantidade, Double.parseDouble(precoCompra), Double.parseDouble(precoAtual), dataCompra, tipo);
if (nome.isEmpty() || quantidade.isEmpty() || precoCompra.isEmpty() || precoAtual.isEmpty() || dataCompra.isEmpty() || spinnerTipoAtivo.getSelectedItemPosition() == 0) {
Toast.makeText(requireContext(), "Por favor, preencha os campos obrigatórios.", Toast.LENGTH_SHORT).show();
} else {
// Aqui seria a lógica para guardar na Firebase
DatabaseReference databaseReference = FirebaseDatabase.getInstance().getReference();
String userId = FirebaseAuth.getInstance().getCurrentUser().getUid();
String key = databaseReference.child("users").child(userId).child("ativos").push().getKey();
databaseReference.child("users").child(userId).child("ativos").child(key).setValue(ativos);
dialog.dismiss();
Toast.makeText(requireContext(), "Ativo adicionado com sucesso!", Toast.LENGTH_SHORT).show();
}
});
dialog.show();
}
}

View File

@@ -1,5 +1,9 @@
package com.example.lifegrid.menu;
import android.app.AlertDialog;
import android.app.DatePickerDialog;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
import androidx.fragment.app.Fragment;
@@ -7,8 +11,19 @@ import androidx.fragment.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.Toast;
import java.util.Calendar;
import java.util.Locale;
import com.example.lifegrid.R;
import com.example.lifegrid.models.Meta;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
/**
* MetasFragment projeta objetivos futuros onde o utilizador fixa montantes e datas a alcançar
@@ -31,7 +46,73 @@ public class MetasFragment extends Fragment {
// Inflaciona o layout para este fragmento
View root = inflater.inflate(R.layout.fragment_metas, container, false);
Button novaTransacaoButton = root.findViewById(R.id.novaTransacaoButton);
novaTransacaoButton.setOnClickListener(v -> showNovaMetaDialog());
return root;
}
private void showNovaMetaDialog() {
AlertDialog.Builder builder = new AlertDialog.Builder(requireContext());
View dialogView = getLayoutInflater().inflate(R.layout.dialog_nova_meta, null);
builder.setView(dialogView);
AlertDialog dialog = builder.create();
if (dialog.getWindow() != null) {
dialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
}
ImageView btnFechar = dialogView.findViewById(R.id.btnFecharMeta);
btnFechar.setOnClickListener(v -> dialog.dismiss());
EditText etDataLimite = dialogView.findViewById(R.id.etDataLimite);
etDataLimite.setOnClickListener(v -> {
Calendar calendar = Calendar.getInstance();
int year = calendar.get(Calendar.YEAR);
int month = calendar.get(Calendar.MONTH);
int day = calendar.get(Calendar.DAY_OF_MONTH);
DatePickerDialog datePickerDialog = new DatePickerDialog(requireContext(),
(view, selectedYear, selectedMonth, selectedDay) -> {
String formattedDate = String.format(Locale.getDefault(), "%02d/%02d/%04d", selectedDay, selectedMonth + 1, selectedYear);
etDataLimite.setText(formattedDate);
}, year, month, day);
datePickerDialog.show();
});
Button btnCriarMetaDialog = dialogView.findViewById(R.id.btnCriarMetaDialog);
EditText etNomeMeta = dialogView.findViewById(R.id.etNomeMeta);
EditText etCategoriaMeta = dialogView.findViewById(R.id.etCategoriaMeta);
EditText etValorObjetivo = dialogView.findViewById(R.id.etValorObjetivo);
btnCriarMetaDialog.setOnClickListener(v -> {
String nome = etNomeMeta.getText().toString().trim();
String categoria = etCategoriaMeta.getText().toString().trim();
String valor = etValorObjetivo.getText().toString().trim();
String data = etDataLimite.getText().toString().trim();
Meta meta = new Meta(nome, categoria, valor, data);
if (nome.isEmpty() || categoria.isEmpty() || valor.isEmpty() || data.isEmpty()) {
Toast.makeText(requireContext(), "Por favor, preencha todos os campos.", Toast.LENGTH_SHORT).show();
} else {
// Aqui seria a lógica para guardar na Firebase
DatabaseReference databaseReference = FirebaseDatabase.getInstance().getReference();
String userId = FirebaseAuth.getInstance().getCurrentUser().getUid();
String key = databaseReference.child("users").child(userId).child("metas").push().getKey();
databaseReference.child("users").child(userId).child("metas").child(key).setValue(meta);
dialog.dismiss();
Toast.makeText(requireContext(), "Meta criada com sucesso!", Toast.LENGTH_SHORT).show();
}
});
dialog.show();
}
}

View File

@@ -0,0 +1,71 @@
package com.example.lifegrid.models;
public class Ativos {
private String nome;
private String quantidade;
private double precoCompra;
private double precoAtual;
private String dataCompra;
private String tipo;
public Ativos() {
}
public Ativos(String nome, String quantidade, double precoCompra, double precoAtual, String dataCompra, String tipo) {
this.nome = nome;
this.quantidade = quantidade;
this.precoCompra = precoCompra;
this.precoAtual = precoAtual;
this.dataCompra = dataCompra;
this.tipo = tipo;
}
public String getNome() {
return nome;
}
public void setNome(String nome) {
this.nome = nome;
}
public String getQuantidade() {
return quantidade;
}
public void setQuantidade(String quantidade) {
this.quantidade = quantidade;
}
public double getPrecoCompra() {
return precoCompra;
}
public void setPrecoCompra(double precoCompra) {
this.precoCompra = precoCompra;
}
public double getPrecoAtual() {
return precoAtual;
}
public void setPrecoAtual(double precoAtual) {
this.precoAtual = precoAtual;
}
public String getDataCompra() {
return dataCompra;
}
public void setDataCompra(String dataCompra) {
this.dataCompra = dataCompra;
}
public String getTipo() {
return tipo;
}
public void setTipo(String tipo) {
this.tipo = tipo;
}
}

View File

@@ -0,0 +1,50 @@
package com.example.lifegrid.models;
public class Meta {
private String nome;
private String categoria;
private String valor;
private String data;
public Meta(){
}
public Meta(String nome, String categoria, String valor, String data) {
this.nome = nome;
this.categoria = categoria;
this.valor = valor;
this.data = data;
}
public String getNome() {
return nome;
}
public void setNome(String nome) {
this.nome = nome;
}
public String getCategoria() {
return categoria;
}
public void setCategoria(String categoria) {
this.categoria = categoria;
}
public String getValor() {
return valor;
}
public void setValor(String valor) {
this.valor = valor;
}
public String getData() {
return data;
}
public void setData(String data) {
this.data = data;
}
}

View File

@@ -73,7 +73,7 @@
android:layout_marginTop="40dp"
android:text="0.00€"
android:textColor="#000000"
android:textSize="28sp"
android:textSize="23sp"
android:textStyle="bold"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tvTitulo" />
@@ -169,7 +169,7 @@
android:layout_marginTop="40dp"
android:text="0.00€"
android:textColor="#000000"
android:textSize="28sp"
android:textSize="23sp"
android:textStyle="bold"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tvTitulo2" />
@@ -240,7 +240,7 @@
android:layout_marginTop="40dp"
android:text="0.00€"
android:textColor="#000000"
android:textSize="28sp"
android:textSize="23sp"
android:textStyle="bold"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tvTitulo3" />
@@ -311,7 +311,7 @@
android:layout_marginTop="40dp"
android:text="0.00€"
android:textColor="#000000"
android:textSize="28sp"
android:textSize="23sp"
android:textStyle="bold"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tvTitulo4" />
@@ -334,7 +334,7 @@
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/barraCardView"
android:layout_width="414dp"
android:layout_width="380dp"
android:layout_height="39dp"
android:layout_marginTop="44dp"
android:background="@drawable/linear_backgound"

View File

@@ -0,0 +1,139 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/dialog_bg"
android:orientation="vertical"
android:padding="24dp">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="24dp">
<TextView
android:id="@+id/dialogTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="Criar Meta Financeira"
android:textColor="@color/preto"
android:textSize="20sp"
android:textStyle="bold" />
<ImageView
android:id="@+id/btnFecharMeta"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
android:src="@android:drawable/ic_menu_close_clear_cancel"
app:tint="@color/preto" />
</RelativeLayout>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:text="Nome da Meta"
android:textColor="@color/preto"
android:textStyle="bold" />
<EditText
android:id="@+id/etNomeMeta"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_marginBottom="16dp"
android:background="@drawable/rounded_input_bg"
android:hint="Ex: Férias de Verão, Fundo de Emergênc"
android:inputType="text"
android:paddingHorizontal="16dp"
android:textColor="@color/preto" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:text="Categoria"
android:textColor="@color/preto"
android:textStyle="bold" />
<EditText
android:id="@+id/etCategoriaMeta"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_marginBottom="16dp"
android:background="@drawable/rounded_input_bg"
android:hint="Ex: Viagem, Poupança, Investimento"
android:inputType="text"
android:paddingHorizontal="16dp"
android:textColor="@color/preto" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:text="Valor Objetivo (€)"
android:textColor="@color/preto"
android:textStyle="bold" />
<EditText
android:id="@+id/etValorObjetivo"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_marginBottom="16dp"
android:background="@drawable/rounded_input_bg"
android:hint="0.00"
android:inputType="numberDecimal"
android:paddingHorizontal="16dp"
android:textColor="@color/preto" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:text="Data Limite"
android:textColor="@color/preto"
android:textStyle="bold" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_marginBottom="16dp"
android:background="@drawable/rounded_input_bg"
android:gravity="center_vertical"
android:orientation="horizontal"
android:paddingHorizontal="16dp">
<EditText
android:id="@+id/etDataLimite"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="@null"
android:hint="dd/mm/aaaa"
android:focusable="false"
android:clickable="true"
android:inputType="none"
android:textColor="@color/preto" />
<ImageView
android:layout_width="24dp"
android:layout_height="24dp"
android:src="@android:drawable/ic_menu_today"
app:tint="@color/cinzaescuro" />
</LinearLayout>
<Button
android:id="@+id/btnCriarMetaDialog"
android:layout_width="match_parent"
android:layout_height="60dp"
android:layout_marginTop="8dp"
android:backgroundTint="@color/preto"
android:text="Criar Meta"
android:textColor="@color/branco"
android:textSize="16sp"
app:cornerRadius="12dp" />
</LinearLayout>

View File

@@ -0,0 +1,175 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/dialog_bg"
android:orientation="vertical"
android:padding="24dp">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="24dp">
<TextView
android:id="@+id/dialogTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="Adicionar Ativo"
android:textColor="@color/preto"
android:textSize="20sp"
android:textStyle="bold" />
<ImageView
android:id="@+id/btnFechar"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
android:src="@android:drawable/ic_menu_close_clear_cancel"
app:tint="@color/preto" />
</RelativeLayout>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:text="Nome do Ativo"
android:textColor="@color/preto"
android:textStyle="bold" />
<EditText
android:id="@+id/etNomeAtivo"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_marginBottom="16dp"
android:background="@drawable/rounded_input_bg"
android:hint="Ex: Apple Inc., Bitcoin, Apartamento Lisl"
android:inputType="text"
android:paddingHorizontal="16dp"
android:textColor="@color/preto" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:text="Tipo"
android:textColor="@color/preto"
android:textStyle="bold" />
<Spinner
android:id="@+id/spinnerTipoAtivo"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_marginBottom="16dp"
android:background="@drawable/rounded_input_bg"
android:entries="@array/tipo_ativo"
android:popupBackground="@drawable/dialog_bg"
android:paddingHorizontal="12dp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:text="Quantidade"
android:textColor="@color/preto"
android:textStyle="bold" />
<EditText
android:id="@+id/etQuantidade"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_marginBottom="16dp"
android:background="@drawable/rounded_input_bg"
android:hint="1"
android:inputType="numberDecimal"
android:paddingHorizontal="16dp"
android:textColor="@color/preto" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:text="Preço de Compra (€)"
android:textColor="@color/preto"
android:textStyle="bold" />
<EditText
android:id="@+id/etPrecoCompra"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_marginBottom="16dp"
android:background="@drawable/rounded_input_bg"
android:hint="0.00"
android:inputType="numberDecimal"
android:paddingHorizontal="16dp"
android:textColor="@color/preto" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:text="Preço Atual (€)"
android:textColor="@color/preto"
android:textStyle="bold" />
<EditText
android:id="@+id/etPrecoAtual"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_marginBottom="16dp"
android:background="@drawable/rounded_input_bg"
android:hint="0.00"
android:inputType="numberDecimal"
android:paddingHorizontal="16dp"
android:textColor="@color/preto" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:text="Data de Compra"
android:textColor="@color/preto"
android:textStyle="bold" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_marginBottom="16dp"
android:background="@drawable/rounded_input_bg"
android:gravity="center_vertical"
android:orientation="horizontal"
android:paddingHorizontal="16dp">
<EditText
android:id="@+id/etDataCompra"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="@null"
android:hint="23/04/2026"
android:focusable="false"
android:clickable="true"
android:inputType="none"
android:textColor="@color/preto" />
<ImageView
android:layout_width="24dp"
android:layout_height="24dp"
android:src="@android:drawable/ic_menu_today"
app:tint="@color/cinzaescuro" />
</LinearLayout>
<Button
android:id="@+id/btnAdicionarAtivoDialog"
android:layout_width="match_parent"
android:layout_height="60dp"
android:backgroundTint="@color/preto"
android:text="Adicionar Ativo"
android:textColor="@color/branco"
android:textSize="16sp"
app:cornerRadius="12dp" />
</LinearLayout>

View File

@@ -38,8 +38,8 @@
android:layout_height="55dp"
android:layout_marginTop="16dp"
android:backgroundTint="@color/preto"
android:text=" + Novo Ativo"
android:textSize="15sp"
android:text=" + Novo Documento"
android:textSize="14sp"
app:cornerRadius="14sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.154"

View File

@@ -29,4 +29,12 @@
<item>Investimentos</item>
<item>Outros</item>
</string-array>
<string-array name="tipo_ativo">
<item>Selecione um tipo</item>
<item>Ações</item>
<item>Fundos</item>
<item>Imóveis</item>
<item>Criptomoedas</item>
</string-array>
</resources>