vamos
This commit is contained in:
@@ -33,6 +33,13 @@ import com.google.firebase.auth.FirebaseAuth;
|
||||
import com.google.firebase.auth.FirebaseUser;
|
||||
import com.google.firebase.auth.GoogleAuthProvider;
|
||||
|
||||
import com.google.firebase.auth.GoogleAuthProvider;
|
||||
|
||||
/**
|
||||
* CriarContaActivity é a atividade responsável por gerir o registo de novos utilizadores na aplicação LifeGrid.
|
||||
* Permite a criação de conta utilizando Email/Password e validações de formulário.
|
||||
* Também suporta registo integrado via conta Google.
|
||||
*/
|
||||
public class CriarContaActivity extends AppCompatActivity {
|
||||
|
||||
private EditText nomeEditText;
|
||||
@@ -68,9 +75,14 @@ public class CriarContaActivity extends AppCompatActivity {
|
||||
firebaseAuth = FirebaseAuth.getInstance();
|
||||
credentialManager = CredentialManager.create(this);
|
||||
|
||||
// Configura o botão de registo para acionar a validação e criação de conta
|
||||
loginButton2.setOnClickListener(v -> criarConta());
|
||||
}
|
||||
|
||||
/**
|
||||
* Extrai os dados dos campos de texto, chama o método de validação,
|
||||
* e caso os dados estejam corretos, regista o utilizador no Firebase Auth.
|
||||
*/
|
||||
private void criarConta() {
|
||||
String nome = nomeEditText.getText().toString().trim();
|
||||
String email = emailEditText2.getText().toString().trim();
|
||||
@@ -119,6 +131,10 @@ public class CriarContaActivity extends AppCompatActivity {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Valida os diferentes campos do formulário para garantir que estão preenchidos
|
||||
* corretamente (tamanho e formato do email) antes de tentar comunicar com o Firebase.
|
||||
*/
|
||||
private boolean validarDados(String nome, String email, String password, String confirmarPassword) {
|
||||
// Validar nome
|
||||
if (TextUtils.isEmpty(nome)) {
|
||||
|
||||
@@ -45,6 +45,11 @@ import com.google.firebase.auth.GoogleAuthProvider;
|
||||
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
/**
|
||||
* LoginActivity é o ecrã inicial da aplicação onde o utilizador fornece as suas credenciais.
|
||||
* Suporta o login regular com Email e Palavra-Passe ligando ao Firebase Auth.
|
||||
* Também suporta autenticação moderna pela API do CredentialManager (Google Sign In).
|
||||
*/
|
||||
public class LoginActivity extends AppCompatActivity {
|
||||
|
||||
private TextView textView5;
|
||||
@@ -106,7 +111,7 @@ public class LoginActivity extends AppCompatActivity {
|
||||
}
|
||||
});
|
||||
|
||||
// Inicialmente desabilitar o TextView de recuperar senha
|
||||
// Inicialmente desabilitar o TextView de recuperar palavra-passe
|
||||
passesquecerTextView.setEnabled(false);
|
||||
passesquecerTextView.setAlpha(0.5f); // Visualmente mais claro quando desabilitado
|
||||
|
||||
@@ -115,11 +120,11 @@ public class LoginActivity extends AppCompatActivity {
|
||||
public void onClick(View view) {
|
||||
String email = emailEditText.getText().toString().trim();
|
||||
|
||||
// Validar se há email antes de abrir a atividade de recuperação
|
||||
// Validar se tem e-mail antes de abrir a atividade de recuperação
|
||||
if (TextUtils.isEmpty(email)) {
|
||||
emailEditText.setError("Por favor, digite seu email primeiro.");
|
||||
emailEditText.setError("Por favor, digite o seu e-mail primeiro.");
|
||||
emailEditText.requestFocus();
|
||||
Toast.makeText(LoginActivity.this, "Digite seu email para recuperar a senha.", Toast.LENGTH_SHORT).show();
|
||||
Toast.makeText(LoginActivity.this, "Digite o seu e-mail para recuperar a palavra-passe.", Toast.LENGTH_SHORT).show();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -147,7 +152,10 @@ public class LoginActivity extends AppCompatActivity {
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Extrai os dados dos campos de Email e Password, executa as funções de validação
|
||||
* e caso os dados estejam em boa forma efetua a requisição de entrada pela plataforma Firebase.
|
||||
*/
|
||||
private void validarLogin() {
|
||||
String email = emailEditText.getText().toString().trim();
|
||||
String password = passwordEditText.getText().toString();
|
||||
@@ -269,19 +277,19 @@ public class LoginActivity extends AppCompatActivity {
|
||||
|
||||
private void launchCredentialManager() {
|
||||
// [START create_credential_manager_request]
|
||||
// Instantiate a Google sign-in request
|
||||
// Instancia um pedido de início de sessão do Google
|
||||
GetGoogleIdOption googleIdOption = new GetGoogleIdOption.Builder()
|
||||
.setFilterByAuthorizedAccounts(true)
|
||||
.setServerClientId(getString(R.string.default_web_client_id))
|
||||
.build();
|
||||
|
||||
// Create the Credential Manager request
|
||||
// Cria o pedido do Gestor de Credenciais
|
||||
GetCredentialRequest request = new GetCredentialRequest.Builder()
|
||||
.addCredentialOption(googleIdOption)
|
||||
.build();
|
||||
// [END create_credential_manager_request]
|
||||
|
||||
// Launch Credential Manager UI
|
||||
// Lança a interface do Gestor de Credenciais
|
||||
credentialManager.getCredentialAsync(
|
||||
getBaseContext(),
|
||||
request,
|
||||
@@ -290,7 +298,7 @@ public class LoginActivity extends AppCompatActivity {
|
||||
new CredentialManagerCallback<>() {
|
||||
@Override
|
||||
public void onResult(GetCredentialResponse result) {
|
||||
// Extract credential from the result returned by Credential Manager
|
||||
// Extrai a credencial do resultado devolvido pelo Gestor de Credenciais
|
||||
handleSignIn(result.getCredential());
|
||||
}
|
||||
|
||||
@@ -303,14 +311,14 @@ public class LoginActivity extends AppCompatActivity {
|
||||
}
|
||||
|
||||
private void handleSignIn(Credential credential) {
|
||||
// Check if credential is of type Google ID
|
||||
// Verifica se a credencial é do tipo Google ID
|
||||
if (credential instanceof CustomCredential customCredential
|
||||
&& credential.getType().equals(GOOGLE_ID_TOKEN_CREDENTIAL)) {
|
||||
// Create Google ID Token
|
||||
// Cria o token do Google ID
|
||||
Bundle credentialData = customCredential.getData();
|
||||
GoogleIdTokenCredential googleIdTokenCredential = GoogleIdTokenCredential.createFrom(credentialData);
|
||||
|
||||
// Sign in to Firebase with using the token
|
||||
// Inicia a sessão no Firebase usando o token
|
||||
firebaseAuthWithGoogle(googleIdTokenCredential.getIdToken());
|
||||
} else {
|
||||
Log.w(TAG, "Credential is not of type Google ID!");
|
||||
@@ -318,10 +326,10 @@ public class LoginActivity extends AppCompatActivity {
|
||||
}
|
||||
|
||||
private void signOut() {
|
||||
// Firebase sign out
|
||||
// Termina a sessão no Firebase
|
||||
mAuth.signOut();
|
||||
|
||||
// When a user signs out, clear the current user credential state from all credential providers.
|
||||
// Quando o utilizador termina a sessão, limpa o estado atual da credencial do utilizador de todos os provedores de credenciais.
|
||||
ClearCredentialStateRequest clearRequest = new ClearCredentialStateRequest();
|
||||
credentialManager.clearCredentialStateAsync(
|
||||
clearRequest,
|
||||
@@ -343,7 +351,7 @@ public class LoginActivity extends AppCompatActivity {
|
||||
@Override
|
||||
public void onStart() {
|
||||
super.onStart();
|
||||
// Check if user is signed in (non-null) and update UI accordingly.
|
||||
// Verifica se o utilizador tem sessão iniciada (não nulo) e atualiza a interface conformemente.
|
||||
FirebaseUser currentUser = mAuth.getCurrentUser();
|
||||
if (currentUser != null) {
|
||||
Intent intent = new Intent(LoginActivity.this, TelaInicialActivity.class);
|
||||
|
||||
@@ -18,6 +18,10 @@ import androidx.core.view.WindowInsetsCompat;
|
||||
import com.google.firebase.FirebaseApp;
|
||||
import com.google.firebase.auth.FirebaseAuth;
|
||||
|
||||
/**
|
||||
* RecupearPasswordActivity é a atividade que coordena o envio do formulário de recuperação de senha.
|
||||
* Liga-se ao Firebase e envia automaticamente um link de redifinição de palavra-passe para a caixa de correio do utilizador.
|
||||
*/
|
||||
public class RecupearPasswordActivity extends AppCompatActivity {
|
||||
|
||||
private EditText emailEditText4;
|
||||
@@ -56,6 +60,10 @@ public class RecupearPasswordActivity extends AppCompatActivity {
|
||||
loginButton3.setOnClickListener(v -> recuperarPassword());
|
||||
}
|
||||
|
||||
/**
|
||||
* Valida o campo do e-mail fornecido pelo utilizador para enviar o pedido
|
||||
* de mudança de palavra-passe aos servidores do serviço Firebase. Trata as respetivas mensagens de sucesso e erro.
|
||||
*/
|
||||
private void recuperarPassword() {
|
||||
String email = emailEditText4.getText().toString().trim();
|
||||
String emailPassado = getIntent().getStringExtra("email");
|
||||
|
||||
@@ -18,6 +18,11 @@ import com.example.lifegrid.menu.GraficosFragment;
|
||||
import com.example.lifegrid.menu.MetasFragment;
|
||||
import com.example.lifegrid.menu.TransacoesFragment;
|
||||
|
||||
/**
|
||||
* TelaInicialActivity funciona como a janela mestre (Container) de navegação da aplicação.
|
||||
* É a responsável por carregar e trocar as visualizações menores (Fragmentos) na área principal do ecrã
|
||||
* mediante o clique numa série de botões situados na barra de fundo.
|
||||
*/
|
||||
public class TelaInicialActivity extends AppCompatActivity {
|
||||
|
||||
private TextView tvValor;
|
||||
|
||||
@@ -10,11 +10,14 @@ import android.view.ViewGroup;
|
||||
|
||||
import com.example.lifegrid.R;
|
||||
|
||||
|
||||
/**
|
||||
* AtivosFragment diz respeito à janela do ecossistema dedicada à gestão
|
||||
* do património estático ou em avaliação progressiva na bolsa/bancos.
|
||||
*/
|
||||
public class AtivosFragment extends Fragment {
|
||||
|
||||
public AtivosFragment() {
|
||||
// Required empty public constructor
|
||||
// Construtor público vazio obrigatório
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -25,7 +28,7 @@ public class AtivosFragment extends Fragment {
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
// Inflate the layout for this fragment
|
||||
// Inflaciona o layout para este fragmento
|
||||
View root = inflater.inflate(R.layout.fragment_ativos, container, false);
|
||||
|
||||
|
||||
|
||||
@@ -10,11 +10,14 @@ import android.view.ViewGroup;
|
||||
|
||||
import com.example.lifegrid.R;
|
||||
|
||||
|
||||
/**
|
||||
* DefinicoesFragment carrega os menus base de configurações do utilizador,
|
||||
* sendo o local ideal para definir opções de acessibilidade, mudança de password e logout.
|
||||
*/
|
||||
public class DefinicoesFragment extends Fragment {
|
||||
|
||||
public DefinicoesFragment() {
|
||||
// Required empty public constructor
|
||||
// Construtor público vazio obrigatório
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -25,7 +28,7 @@ public class DefinicoesFragment extends Fragment {
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
// Inflate the layout for this fragment
|
||||
// Inflaciona o layout para este fragmento
|
||||
View root = inflater.inflate(R.layout.fragment_definicoes, container, false);
|
||||
|
||||
|
||||
|
||||
@@ -10,11 +10,14 @@ import android.view.ViewGroup;
|
||||
|
||||
import com.example.lifegrid.R;
|
||||
|
||||
|
||||
/**
|
||||
* DocumentosFragment é a área orientada ao scan, compilação de faturas e arquivo seguro.
|
||||
* Foca-se unicamente nas componentes não contabéis mas sim em anotações em anexo faturado.
|
||||
*/
|
||||
public class DocumentosFragment extends Fragment {
|
||||
|
||||
public DocumentosFragment() {
|
||||
// Required empty public constructor
|
||||
// Construtor público vazio obrigatório
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -25,7 +28,7 @@ public class DocumentosFragment extends Fragment {
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
// Inflate the layout for this fragment
|
||||
// Inflaciona o layout para este fragmento
|
||||
View root = inflater.inflate(R.layout.fragment_documentos, container, false);
|
||||
|
||||
|
||||
|
||||
@@ -10,10 +10,14 @@ import android.view.ViewGroup;
|
||||
|
||||
import com.example.lifegrid.R;
|
||||
|
||||
/**
|
||||
* GraficosFragment tem como único propósito compilar a informação da aplicação sob uma
|
||||
* componente puramente matemática exibida de forma ilustrativa. Tarta da visão de Dashboard de estatística.
|
||||
*/
|
||||
public class GraficosFragment extends Fragment {
|
||||
|
||||
public GraficosFragment() {
|
||||
// Required empty public constructor
|
||||
// Construtor público vazio obrigatório
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -24,7 +28,7 @@ public class GraficosFragment extends Fragment {
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
// Inflate the layout for this fragment
|
||||
// Inflaciona o layout para este fragmento
|
||||
View root = inflater.inflate(R.layout.fragment_graficos, container, false);
|
||||
|
||||
|
||||
|
||||
@@ -10,10 +10,14 @@ import android.view.ViewGroup;
|
||||
|
||||
import com.example.lifegrid.R;
|
||||
|
||||
/**
|
||||
* MetasFragment projeta objetivos futuros onde o utilizador fixa montantes e datas a alcançar
|
||||
* sendo apresentada percentagem de sucesso à medida que deposita fundos dedicados.
|
||||
*/
|
||||
public class MetasFragment extends Fragment {
|
||||
|
||||
public MetasFragment() {
|
||||
// Required empty public constructor
|
||||
// Construtor público vazio obrigatório
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -24,7 +28,7 @@ public class MetasFragment extends Fragment {
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
// Inflate the layout for this fragment
|
||||
// Inflaciona o layout para este fragmento
|
||||
View root = inflater.inflate(R.layout.fragment_metas, container, false);
|
||||
|
||||
|
||||
|
||||
@@ -8,15 +8,40 @@ import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.app.DatePickerDialog;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.Button;
|
||||
import android.widget.EditText;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.Spinner;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import java.util.Calendar;
|
||||
import java.util.Locale;
|
||||
|
||||
import com.example.lifegrid.R;
|
||||
import com.example.lifegrid.models.Transacao;
|
||||
import com.google.firebase.Firebase;
|
||||
import com.google.firebase.auth.FirebaseAuth;
|
||||
import com.google.firebase.auth.FirebaseUser;
|
||||
import com.google.firebase.database.DatabaseReference;
|
||||
import com.google.firebase.database.FirebaseDatabase;
|
||||
|
||||
|
||||
/**
|
||||
* TransacoesFragment controla a aba pertencente às listagens e histórico de carteira e gestão de dados base.
|
||||
* É responsável por permitir o lançamento do pop-up para a construção de novas entradas financeiras (receitas/despesas).
|
||||
*/
|
||||
public class TransacoesFragment extends Fragment {
|
||||
|
||||
|
||||
|
||||
public TransacoesFragment() {
|
||||
// Required empty public constructor
|
||||
// Construtor público vazio obrigatório
|
||||
}
|
||||
|
||||
|
||||
@@ -29,10 +54,93 @@ public class TransacoesFragment extends Fragment {
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
// Inflate the layout for this fragment
|
||||
// Inflaciona o layout para este fragmento
|
||||
View root = inflater.inflate(R.layout.fragment_transacoes, container, false);
|
||||
|
||||
Button novaTransacaoButton = root.findViewById(R.id.novaTransacaoButton);
|
||||
novaTransacaoButton.setOnClickListener(v -> showNovaTransacaoDialog());
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cria e monta manualmente uma janela Modal (Pop-up) a fim do utilizador preencher
|
||||
* os detalhes referentes a uma recém aquisição de receita ou encargo para alimentar a base de dados.
|
||||
*/
|
||||
private void showNovaTransacaoDialog() {
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(requireContext());
|
||||
View dialogView = getLayoutInflater().inflate(R.layout.dialog_nova_transacao, 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 etData = dialogView.findViewById(R.id.etData);
|
||||
etData.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);
|
||||
etData.setText(formattedDate);
|
||||
}, year, month, day);
|
||||
datePickerDialog.show();
|
||||
});
|
||||
|
||||
Button btnAdicionarTransacao = dialogView.findViewById(R.id.btnAdicionarTransacao);
|
||||
EditText etValor = dialogView.findViewById(R.id.etValor);
|
||||
EditText etDescricao = dialogView.findViewById(R.id.etDescricao);
|
||||
Spinner spinnerCategoria = dialogView.findViewById(R.id.spinnerCategoria);
|
||||
Spinner spinnerTipo = dialogView.findViewById(R.id.spinnerTipo);
|
||||
|
||||
spinnerTipo.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
|
||||
@Override
|
||||
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
|
||||
int arrayResId = position == 0 ? R.array.categoria_receita : R.array.categoria_despesa;
|
||||
ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(requireContext(),
|
||||
arrayResId, android.R.layout.simple_spinner_item);
|
||||
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
||||
spinnerCategoria.setAdapter(adapter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNothingSelected(AdapterView<?> parent) {
|
||||
}
|
||||
});
|
||||
|
||||
btnAdicionarTransacao.setOnClickListener(v -> {
|
||||
String valor = etValor.getText().toString().trim();
|
||||
String descricao = etDescricao.getText().toString().trim();
|
||||
String data = etData.getText().toString().trim();
|
||||
String tipo = spinnerTipo.getSelectedItem().toString();
|
||||
String categoria = spinnerCategoria.getSelectedItem().toString();
|
||||
|
||||
Transacao transacao = new Transacao(tipo, valor, categoria, descricao, data);
|
||||
|
||||
|
||||
if (valor.isEmpty() || descricao.isEmpty() || data.isEmpty() || spinnerCategoria.getSelectedItemPosition() == 0) {
|
||||
Toast.makeText(requireContext(), "Por favor, preencha todos os campos.", Toast.LENGTH_SHORT).show();
|
||||
} else {
|
||||
DatabaseReference databaseReference = FirebaseDatabase.getInstance().getReference();
|
||||
String userId = FirebaseAuth.getInstance().getCurrentUser().getUid();
|
||||
String key = databaseReference.child("users").child(userId).child("transacoes").push().getKey();
|
||||
|
||||
databaseReference.child("users").child(userId).child("transacoes").child(key).setValue(transacao);
|
||||
|
||||
|
||||
dialog.dismiss();
|
||||
Toast.makeText(requireContext(), "Transação adicionada com sucesso!", Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
});
|
||||
|
||||
dialog.show();
|
||||
}
|
||||
}
|
||||
61
app/src/main/java/com/example/lifegrid/models/Transacao.java
Normal file
61
app/src/main/java/com/example/lifegrid/models/Transacao.java
Normal file
@@ -0,0 +1,61 @@
|
||||
package com.example.lifegrid.models;
|
||||
|
||||
public class Transacao {
|
||||
private String tipo;
|
||||
private String valor;
|
||||
private String categoria;
|
||||
private String descricao;
|
||||
private String data;
|
||||
|
||||
public Transacao() {
|
||||
}
|
||||
|
||||
|
||||
public Transacao(String tipo, String valor, String categoria, String descricao, String data) {
|
||||
this.tipo = tipo;
|
||||
this.valor = valor;
|
||||
this.categoria = categoria;
|
||||
this.descricao = descricao;
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
public String getTipo() {
|
||||
return tipo;
|
||||
}
|
||||
|
||||
public void setTipo(String tipo) {
|
||||
this.tipo = tipo;
|
||||
}
|
||||
|
||||
public String getValor() {
|
||||
return valor;
|
||||
}
|
||||
|
||||
public void setValor(String valor) {
|
||||
this.valor = valor;
|
||||
}
|
||||
|
||||
public String getCategoria() {
|
||||
return categoria;
|
||||
}
|
||||
|
||||
public void setCategoria(String categoria) {
|
||||
this.categoria = categoria;
|
||||
}
|
||||
|
||||
public String getDescricao() {
|
||||
return descricao;
|
||||
}
|
||||
|
||||
public void setDescricao(String descricao) {
|
||||
this.descricao = descricao;
|
||||
}
|
||||
|
||||
public String getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
public void setData(String data) {
|
||||
this.data = data;
|
||||
}
|
||||
}
|
||||
5
app/src/main/res/drawable/dialog_bg.xml
Normal file
5
app/src/main/res/drawable/dialog_bg.xml
Normal file
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<solid android:color="@color/branco"/>
|
||||
<corners android:radius="20dp"/>
|
||||
</shape>
|
||||
6
app/src/main/res/drawable/rounded_input_bg.xml
Normal file
6
app/src/main/res/drawable/rounded_input_bg.xml
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
<solid android:color="#F2F2F2" />
|
||||
<corners android:radius="12dp" />
|
||||
</shape>
|
||||
154
app/src/main/res/layout/dialog_nova_transacao.xml
Normal file
154
app/src/main/res/layout/dialog_nova_transacao.xml
Normal file
@@ -0,0 +1,154 @@
|
||||
<?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 Transação"
|
||||
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="Tipo"
|
||||
android:textColor="@color/preto"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<Spinner
|
||||
android:id="@+id/spinnerTipo"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="50dp"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:background="@drawable/rounded_input_bg"
|
||||
android:entries="@array/tipo_transacao"
|
||||
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="Valor (€)"
|
||||
android:textColor="@color/preto"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/etValor"
|
||||
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="Categoria"
|
||||
android:textColor="@color/preto"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<Spinner
|
||||
android:id="@+id/spinnerCategoria"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="50dp"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:background="@drawable/rounded_input_bg"
|
||||
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="Descrição"
|
||||
android:textColor="@color/preto"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/etDescricao"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="50dp"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:background="@drawable/rounded_input_bg"
|
||||
android:hint="Ex: Compras no supermercado"
|
||||
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="Data"
|
||||
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/etData"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1"
|
||||
android:background="@null"
|
||||
android:hint="21/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/btnAdicionarTransacao"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="60dp"
|
||||
android:backgroundTint="@color/preto"
|
||||
android:text="Adicionar Transação"
|
||||
android:textColor="@color/branco"
|
||||
android:textSize="16sp"
|
||||
app:cornerRadius="12dp" />
|
||||
|
||||
</LinearLayout>
|
||||
@@ -75,6 +75,7 @@
|
||||
app:layout_constraintTop_toBottomOf="@+id/textView12" />
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/rvTransacoes"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="211dp"
|
||||
android:layout_marginStart="16dp"
|
||||
|
||||
@@ -4,4 +4,29 @@
|
||||
<!-- TODO: Remove or change this placeholder text -->
|
||||
<string name="hello_blank_fragment">Hello blank fragment</string>
|
||||
<!-- Substitua pelo Web Client ID do Firebase Console -> Authentication -> Sign-in method -> Google -->
|
||||
|
||||
<string-array name="tipo_transacao">
|
||||
<item>Receita</item>
|
||||
<item>Despesa</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="categoria_despesa">
|
||||
<item>Selecione uma categoria</item>
|
||||
<item>Renda</item>
|
||||
<item>Alimentação</item>
|
||||
<item>Lazer</item>
|
||||
<item>Transporte</item>
|
||||
<item>Saúde</item>
|
||||
<item>Educação</item>
|
||||
<item>Utilities</item>
|
||||
<item>Outros</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="categoria_receita">
|
||||
<item>Selecione uma categoria</item>
|
||||
<item>Salário</item>
|
||||
<item>Freelance</item>
|
||||
<item>Investimentos</item>
|
||||
<item>Outros</item>
|
||||
</string-array>
|
||||
</resources>
|
||||
Reference in New Issue
Block a user