Compare commits
46 Commits
ec9a97c5af
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 894c9a845c | |||
| 337440eb91 | |||
| 421ba7c2e2 | |||
| 2087572fa9 | |||
| e797216506 | |||
| 695e8cac2e | |||
| beede716c6 | |||
| e2c3d0badd | |||
| 7e70721c6c | |||
| e1150b3bf0 | |||
| e7aa23bbec | |||
| 2d27e4a227 | |||
| 24acb90d58 | |||
| 371a298636 | |||
| cd527224bf | |||
| 214d51d36e | |||
| 750e91538c | |||
| f034364a41 | |||
| a70395f258 | |||
| 1dbbcb9a78 | |||
| 47a436c97d | |||
| 66746a459a | |||
| e06b4be7bf | |||
| 6618e27afe | |||
| ae62000ff3 | |||
| 62d2a6bb51 | |||
| fc4f786739 | |||
| ca26b8e146 | |||
| b297ff0e6e | |||
| 2e47ced7c7 | |||
| fe0dbed813 | |||
| f2ece221b6 | |||
| 743ddeb3db | |||
| 85a1907ef8 | |||
| 2d4d229eac | |||
| 4b766067f4 | |||
| 460b719785 | |||
| 81eb71bd46 | |||
| 49ba834e96 | |||
| 4d80a9a27d | |||
| 9875c82e65 | |||
| 66d019d9b6 | |||
| 57056bbd6e | |||
| f8cc655f74 | |||
| 363ddad842 | |||
| 65a662a54c |
8
.idea/deploymentTargetSelector.xml
generated
@@ -4,14 +4,6 @@
|
|||||||
<selectionStates>
|
<selectionStates>
|
||||||
<SelectionState runConfigName="app">
|
<SelectionState runConfigName="app">
|
||||||
<option name="selectionMode" value="DROPDOWN" />
|
<option name="selectionMode" value="DROPDOWN" />
|
||||||
<DropdownSelection timestamp="2025-11-26T09:17:18.598825Z">
|
|
||||||
<Target type="DEFAULT_BOOT">
|
|
||||||
<handle>
|
|
||||||
<DeviceId pluginId="LocalEmulator" identifier="path=/Users/230421/.android/avd/Medium_Phone.avd" />
|
|
||||||
</handle>
|
|
||||||
</Target>
|
|
||||||
</DropdownSelection>
|
|
||||||
<DialogSelection />
|
|
||||||
</SelectionState>
|
</SelectionState>
|
||||||
</selectionStates>
|
</selectionStates>
|
||||||
</component>
|
</component>
|
||||||
|
|||||||
7
.idea/misc.xml
generated
@@ -6,4 +6,11 @@
|
|||||||
<component name="ProjectType">
|
<component name="ProjectType">
|
||||||
<option name="id" value="Android" />
|
<option name="id" value="Android" />
|
||||||
</component>
|
</component>
|
||||||
|
<component name="VisualizationToolProject">
|
||||||
|
<option name="state">
|
||||||
|
<ProjectState>
|
||||||
|
<option name="scale" value="0.2492626953125" />
|
||||||
|
</ProjectState>
|
||||||
|
</option>
|
||||||
|
</component>
|
||||||
</project>
|
</project>
|
||||||
@@ -46,6 +46,7 @@ dependencies {
|
|||||||
implementation(libs.credentials.play.services.auth)
|
implementation(libs.credentials.play.services.auth)
|
||||||
implementation(libs.googleid)
|
implementation(libs.googleid)
|
||||||
implementation(libs.firebase.database)
|
implementation(libs.firebase.database)
|
||||||
|
implementation(libs.firebase.storage)
|
||||||
implementation(libs.lifecycle.livedata.ktx)
|
implementation(libs.lifecycle.livedata.ktx)
|
||||||
implementation(libs.lifecycle.viewmodel.ktx)
|
implementation(libs.lifecycle.viewmodel.ktx)
|
||||||
implementation(libs.navigation.fragment)
|
implementation(libs.navigation.fragment)
|
||||||
@@ -53,4 +54,5 @@ dependencies {
|
|||||||
testImplementation(libs.junit)
|
testImplementation(libs.junit)
|
||||||
androidTestImplementation(libs.ext.junit)
|
androidTestImplementation(libs.ext.junit)
|
||||||
androidTestImplementation(libs.espresso.core)
|
androidTestImplementation(libs.espresso.core)
|
||||||
|
implementation("com.github.bumptech.glide:glide:4.16.0")
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
{
|
{
|
||||||
"project_info": {
|
"project_info": {
|
||||||
"project_number": "89853204936",
|
"project_number": "89853204936",
|
||||||
|
"firebase_url": "https://vdcscore-default-rtdb.firebaseio.com",
|
||||||
"project_id": "vdcscore",
|
"project_id": "vdcscore",
|
||||||
"storage_bucket": "vdcscore.firebasestorage.app"
|
"storage_bucket": "vdcscore.firebasestorage.app"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -2,6 +2,11 @@
|
|||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:tools="http://schemas.android.com/tools">
|
xmlns:tools="http://schemas.android.com/tools">
|
||||||
|
|
||||||
|
<uses-permission android:name="android.permission.INTERNET"/>
|
||||||
|
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||||
|
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
|
||||||
|
<uses-permission android:name="android.permission.CAMERA" />
|
||||||
|
|
||||||
<application
|
<application
|
||||||
android:allowBackup="true"
|
android:allowBackup="true"
|
||||||
android:dataExtractionRules="@xml/data_extraction_rules"
|
android:dataExtractionRules="@xml/data_extraction_rules"
|
||||||
@@ -31,6 +36,9 @@
|
|||||||
<category android:name="android.intent.category.LAUNCHER" />
|
<category android:name="android.intent.category.LAUNCHER" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
|
<activity
|
||||||
|
android:name=".RecuperarPasswordActivity"
|
||||||
|
android:exported="false" />
|
||||||
</application>
|
</application>
|
||||||
|
|
||||||
</manifest>
|
</manifest>
|
||||||
@@ -4,7 +4,6 @@ import android.content.Intent;
|
|||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.Button;
|
import android.widget.Button;
|
||||||
import android.widget.EditText;
|
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
@@ -14,6 +13,7 @@ import androidx.core.graphics.Insets;
|
|||||||
import androidx.core.view.ViewCompat;
|
import androidx.core.view.ViewCompat;
|
||||||
import androidx.core.view.WindowInsetsCompat;
|
import androidx.core.view.WindowInsetsCompat;
|
||||||
|
|
||||||
|
import com.google.android.material.textfield.TextInputEditText;
|
||||||
import com.google.firebase.auth.FirebaseAuth;
|
import com.google.firebase.auth.FirebaseAuth;
|
||||||
|
|
||||||
public class CriarContaActivity extends AppCompatActivity {
|
public class CriarContaActivity extends AppCompatActivity {
|
||||||
@@ -28,14 +28,15 @@ public class CriarContaActivity extends AppCompatActivity {
|
|||||||
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);
|
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);
|
||||||
return insets;
|
return insets;
|
||||||
});
|
});
|
||||||
EditText editPassword2;
|
TextInputEditText editPassword2;
|
||||||
EditText editEmail;
|
TextInputEditText editEmail;
|
||||||
EditText editConfirmPassword;
|
TextInputEditText editUserName;
|
||||||
|
TextInputEditText editConfirmPassword;
|
||||||
Button btnCreateAccount;
|
Button btnCreateAccount;
|
||||||
TextView txtGoLogin;
|
TextView txtGoLogin;
|
||||||
|
|
||||||
|
|
||||||
editEmail = findViewById(R.id.editEmail);
|
editEmail = findViewById(R.id.editEmail);
|
||||||
|
editUserName = findViewById(R.id.editUserName);
|
||||||
editPassword2 = findViewById(R.id.editPassword2);
|
editPassword2 = findViewById(R.id.editPassword2);
|
||||||
editConfirmPassword = findViewById(R.id.editConfirmPassword);
|
editConfirmPassword = findViewById(R.id.editConfirmPassword);
|
||||||
btnCreateAccount = findViewById(R.id.btnCreateAccount);
|
btnCreateAccount = findViewById(R.id.btnCreateAccount);
|
||||||
@@ -45,11 +46,12 @@ public class CriarContaActivity extends AppCompatActivity {
|
|||||||
btnCreateAccount.setOnClickListener(new View.OnClickListener() {
|
btnCreateAccount.setOnClickListener(new View.OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
String email = editEmail.getText().toString();
|
String email = editEmail.getText().toString().trim();
|
||||||
String pass = editPassword2.getText().toString();
|
String userName = editUserName.getText().toString().trim();
|
||||||
String conf = editConfirmPassword.getText().toString();
|
String pass = editPassword2.getText().toString().trim();
|
||||||
|
String conf = editConfirmPassword.getText().toString().trim();
|
||||||
|
|
||||||
if (email.isEmpty() || pass.isEmpty() || conf.isEmpty()) {
|
if (email.isEmpty() || userName.isEmpty() || pass.isEmpty() || conf.isEmpty()) {
|
||||||
Toast.makeText(CriarContaActivity.this, "Preencha todos os campos!", Toast.LENGTH_SHORT).show();
|
Toast.makeText(CriarContaActivity.this, "Preencha todos os campos!", Toast.LENGTH_SHORT).show();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -60,14 +62,32 @@ public class CriarContaActivity extends AppCompatActivity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
FirebaseAuth auth = FirebaseAuth.getInstance();
|
FirebaseAuth auth = FirebaseAuth.getInstance();
|
||||||
auth.createUserWithEmailAndPassword(email, pass).addOnCompleteListener(CriarContaActivity.this, task -> {
|
auth.createUserWithEmailAndPassword(email, pass).addOnCompleteListener(CriarContaActivity.this,
|
||||||
|
task -> {
|
||||||
if (task.isSuccessful()) {
|
if (task.isSuccessful()) {
|
||||||
|
// Atualizar nome de utilizador
|
||||||
|
com.google.firebase.auth.FirebaseUser user = auth.getCurrentUser();
|
||||||
|
if (user != null) {
|
||||||
|
com.google.firebase.auth.UserProfileChangeRequest profileUpdates = new com.google.firebase.auth.UserProfileChangeRequest.Builder()
|
||||||
|
.setDisplayName(userName)
|
||||||
|
.build();
|
||||||
|
|
||||||
Intent intent= new Intent(CriarContaActivity.this, MainActivity.class);
|
user.updateProfile(profileUpdates).addOnCompleteListener(updateTask -> {
|
||||||
|
Intent intent = new Intent(CriarContaActivity.this, MainActivity.class);
|
||||||
startActivity(intent);
|
startActivity(intent);
|
||||||
finish();
|
finish();
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
Toast.makeText(CriarContaActivity.this, "Erro ao criar conta!", Toast.LENGTH_SHORT).show();
|
Intent intent = new Intent(CriarContaActivity.this, MainActivity.class);
|
||||||
|
startActivity(intent);
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
String errorMessage = "Erro ao criar conta!";
|
||||||
|
if (task.getException() != null && task.getException().getMessage() != null) {
|
||||||
|
errorMessage = "Erro: " + task.getException().getMessage();
|
||||||
|
}
|
||||||
|
Toast.makeText(CriarContaActivity.this, errorMessage, Toast.LENGTH_LONG).show();
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,23 +1,32 @@
|
|||||||
package com.example.vdcscore;
|
package com.example.vdcscore;
|
||||||
|
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
import android.content.SharedPreferences;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.widget.Button;
|
import android.widget.Button;
|
||||||
import android.widget.EditText;
|
import android.widget.CheckBox;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
import androidx.appcompat.app.AppCompatActivity;
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
|
|
||||||
|
import com.google.android.material.textfield.TextInputEditText;
|
||||||
import com.google.firebase.auth.FirebaseAuth;
|
import com.google.firebase.auth.FirebaseAuth;
|
||||||
|
|
||||||
public class LoginActivity extends AppCompatActivity {
|
public class LoginActivity extends AppCompatActivity {
|
||||||
|
|
||||||
EditText editEmail, editPassword;
|
TextInputEditText editEmail, editPassword;
|
||||||
Button btnLogin;
|
Button btnLogin;
|
||||||
|
CheckBox checkRememberMe;
|
||||||
FirebaseAuth mAuth;
|
FirebaseAuth mAuth;
|
||||||
|
|
||||||
private TextView criarContaTextView;
|
private TextView criarContaTextView;
|
||||||
|
private TextView txtForgotPassword;
|
||||||
|
|
||||||
|
private static final String PREFS_NAME = "LoginPrefs";
|
||||||
|
private static final String KEY_EMAIL = "email";
|
||||||
|
private static final String KEY_PASSWORD = "password";
|
||||||
|
private static final String KEY_REMEMBER = "remember";
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
@@ -27,12 +36,54 @@ public class LoginActivity extends AppCompatActivity {
|
|||||||
editEmail = findViewById(R.id.editEmail);
|
editEmail = findViewById(R.id.editEmail);
|
||||||
editPassword = findViewById(R.id.editPassword2);
|
editPassword = findViewById(R.id.editPassword2);
|
||||||
btnLogin = findViewById(R.id.btnLogin);
|
btnLogin = findViewById(R.id.btnLogin);
|
||||||
|
checkRememberMe = findViewById(R.id.checkRememberMe);
|
||||||
criarContaTextView = findViewById(R.id.txtRegister);
|
criarContaTextView = findViewById(R.id.txtRegister);
|
||||||
|
txtForgotPassword = findViewById(R.id.txtForgotPassword);
|
||||||
|
|
||||||
mAuth = FirebaseAuth.getInstance();
|
mAuth = FirebaseAuth.getInstance();
|
||||||
|
|
||||||
btnLogin.setOnClickListener(v -> loginUser());
|
btnLogin.setOnClickListener(v -> loginUser());
|
||||||
criarContaTextView.setOnClickListener(view -> criarConta());
|
criarContaTextView.setOnClickListener(view -> criarConta());
|
||||||
|
txtForgotPassword.setOnClickListener(view -> recuperarPassword());
|
||||||
|
|
||||||
|
// Carregar credenciais guardadas
|
||||||
|
loadSavedCredentials();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loadSavedCredentials() {
|
||||||
|
SharedPreferences prefs = getSharedPreferences(PREFS_NAME, MODE_PRIVATE);
|
||||||
|
boolean remember = prefs.getBoolean(KEY_REMEMBER, false);
|
||||||
|
|
||||||
|
if (remember) {
|
||||||
|
String savedEmail = prefs.getString(KEY_EMAIL, "");
|
||||||
|
String savedPassword = prefs.getString(KEY_PASSWORD, "");
|
||||||
|
|
||||||
|
if (!savedEmail.isEmpty() && !savedPassword.isEmpty()) {
|
||||||
|
editEmail.setText(savedEmail);
|
||||||
|
editPassword.setText(savedPassword);
|
||||||
|
checkRememberMe.setChecked(true);
|
||||||
|
|
||||||
|
// Tentar login automático
|
||||||
|
autoLogin(savedEmail, savedPassword);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void autoLogin(String email, String password) {
|
||||||
|
mAuth.signInWithEmailAndPassword(email, password)
|
||||||
|
.addOnCompleteListener(task -> {
|
||||||
|
if (task.isSuccessful()) {
|
||||||
|
// Login automático bem-sucedido
|
||||||
|
Intent intent = new Intent(LoginActivity.this, MainActivity.class);
|
||||||
|
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
|
||||||
|
startActivity(intent);
|
||||||
|
finish();
|
||||||
|
} else {
|
||||||
|
// Se o login automático falhar, apenas limpar a password do campo
|
||||||
|
// O utilizador pode tentar fazer login manualmente
|
||||||
|
editPassword.setText("");
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void criarConta() {
|
private void criarConta() {
|
||||||
@@ -40,6 +91,11 @@ public class LoginActivity extends AppCompatActivity {
|
|||||||
startActivity(intent);
|
startActivity(intent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void recuperarPassword() {
|
||||||
|
Intent intent = new Intent(LoginActivity.this, RecuperarPasswordActivity.class);
|
||||||
|
startActivity(intent);
|
||||||
|
}
|
||||||
|
|
||||||
private void loginUser() {
|
private void loginUser() {
|
||||||
String email = editEmail.getText().toString().trim();
|
String email = editEmail.getText().toString().trim();
|
||||||
String password = editPassword.getText().toString().trim();
|
String password = editPassword.getText().toString().trim();
|
||||||
@@ -52,27 +108,56 @@ public class LoginActivity extends AppCompatActivity {
|
|||||||
mAuth.signInWithEmailAndPassword(email, password)
|
mAuth.signInWithEmailAndPassword(email, password)
|
||||||
.addOnCompleteListener(task -> {
|
.addOnCompleteListener(task -> {
|
||||||
if (task.isSuccessful()) {
|
if (task.isSuccessful()) {
|
||||||
|
// Guardar credenciais se "Lembrar-me" estiver marcado
|
||||||
|
if (checkRememberMe.isChecked()) {
|
||||||
|
saveCredentials(email, password);
|
||||||
|
} else {
|
||||||
|
clearSavedCredentials();
|
||||||
|
}
|
||||||
|
|
||||||
Toast.makeText(this, "Login efetuado!", Toast.LENGTH_SHORT).show();
|
Toast.makeText(this, "Login efetuado!", Toast.LENGTH_SHORT).show();
|
||||||
|
|
||||||
// Abre a tua página principal
|
// Abre a tua página principal
|
||||||
startActivity(new Intent(LoginActivity.this, MainActivity.class));
|
Intent intent = new Intent(LoginActivity.this, MainActivity.class);
|
||||||
|
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
|
||||||
|
startActivity(intent);
|
||||||
finish();
|
finish();
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
Toast.makeText(this,
|
String errorMessage = "Erro ao fazer login!";
|
||||||
"Erro: " + task.getException().getMessage(),
|
if (task.getException() != null && task.getException().getMessage() != null) {
|
||||||
Toast.LENGTH_LONG).show();
|
errorMessage = "Erro: " + task.getException().getMessage();
|
||||||
|
}
|
||||||
|
Toast.makeText(this, errorMessage, Toast.LENGTH_LONG).show();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void saveCredentials(String email, String password) {
|
||||||
|
SharedPreferences prefs = getSharedPreferences(PREFS_NAME, MODE_PRIVATE);
|
||||||
|
SharedPreferences.Editor editor = prefs.edit();
|
||||||
|
editor.putString(KEY_EMAIL, email);
|
||||||
|
editor.putString(KEY_PASSWORD, password);
|
||||||
|
editor.putBoolean(KEY_REMEMBER, true);
|
||||||
|
editor.apply();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void clearSavedCredentials() {
|
||||||
|
SharedPreferences prefs = getSharedPreferences(PREFS_NAME, MODE_PRIVATE);
|
||||||
|
SharedPreferences.Editor editor = prefs.edit();
|
||||||
|
editor.clear();
|
||||||
|
editor.apply();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onStart() {
|
protected void onStart() {
|
||||||
super.onStart();
|
super.onStart();
|
||||||
|
// Verificar se já está autenticado (caso o login automático não tenha funcionado)
|
||||||
if (FirebaseAuth.getInstance().getCurrentUser() != null){
|
if (FirebaseAuth.getInstance().getCurrentUser() != null){
|
||||||
Intent intent = new Intent(LoginActivity.this, MainActivity.class);
|
Intent intent = new Intent(LoginActivity.this, MainActivity.class);
|
||||||
|
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
|
||||||
startActivity(intent);
|
startActivity(intent);
|
||||||
|
finish();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,8 +1,12 @@
|
|||||||
package com.example.vdcscore;
|
package com.example.vdcscore;
|
||||||
|
|
||||||
|
import android.graphics.Bitmap;
|
||||||
|
import android.graphics.BitmapFactory;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
|
import android.widget.ImageView;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
import com.google.android.material.snackbar.Snackbar;
|
import com.google.android.material.snackbar.Snackbar;
|
||||||
import com.google.android.material.navigation.NavigationView;
|
import com.google.android.material.navigation.NavigationView;
|
||||||
@@ -15,45 +19,203 @@ import androidx.drawerlayout.widget.DrawerLayout;
|
|||||||
import androidx.appcompat.app.AppCompatActivity;
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
|
|
||||||
import com.example.vdcscore.databinding.ActivityMainBinding;
|
import com.example.vdcscore.databinding.ActivityMainBinding;
|
||||||
|
import com.google.firebase.auth.FirebaseAuth;
|
||||||
|
import com.google.firebase.auth.FirebaseUser;
|
||||||
|
|
||||||
|
import java.io.InputStream;
|
||||||
|
import android.app.AlertDialog;
|
||||||
|
import android.content.DialogInterface;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.net.Uri;
|
||||||
|
import android.text.InputType;
|
||||||
|
import android.widget.EditText;
|
||||||
|
import android.widget.Toast;
|
||||||
|
import androidx.activity.result.ActivityResultLauncher;
|
||||||
|
import androidx.activity.result.contract.ActivityResultContracts;
|
||||||
|
import com.google.firebase.storage.StorageReference;
|
||||||
|
import com.google.firebase.storage.UploadTask;
|
||||||
|
import com.google.firebase.auth.UserProfileChangeRequest;
|
||||||
|
|
||||||
public class MainActivity extends AppCompatActivity {
|
public class MainActivity extends AppCompatActivity {
|
||||||
|
|
||||||
private AppBarConfiguration mAppBarConfiguration;
|
private AppBarConfiguration mAppBarConfiguration;
|
||||||
private ActivityMainBinding binding;
|
private ActivityMainBinding binding;
|
||||||
|
private ActivityResultLauncher<String> mGetContent;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
|
// Carregar preferência do Dark Mode
|
||||||
|
android.content.SharedPreferences prefs = getSharedPreferences("SettingsPrefs",
|
||||||
|
android.content.Context.MODE_PRIVATE);
|
||||||
|
boolean isDarkMode = prefs.getBoolean("dark_mode", false);
|
||||||
|
if (isDarkMode) {
|
||||||
|
androidx.appcompat.app.AppCompatDelegate
|
||||||
|
.setDefaultNightMode(androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_YES);
|
||||||
|
} else {
|
||||||
|
androidx.appcompat.app.AppCompatDelegate
|
||||||
|
.setDefaultNightMode(androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_NO);
|
||||||
|
}
|
||||||
|
|
||||||
binding = ActivityMainBinding.inflate(getLayoutInflater());
|
binding = ActivityMainBinding.inflate(getLayoutInflater());
|
||||||
setContentView(binding.getRoot());
|
setContentView(binding.getRoot());
|
||||||
|
|
||||||
setSupportActionBar(binding.appBarMain.toolbar);
|
setSupportActionBar(binding.appBarMain.toolbar);
|
||||||
binding.appBarMain.fab.setOnClickListener(new View.OnClickListener() {
|
|
||||||
@Override
|
|
||||||
public void onClick(View view) {
|
|
||||||
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
|
|
||||||
.setAction("Action", null)
|
|
||||||
.setAnchorView(R.id.fab).show();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
DrawerLayout drawer = binding.drawerLayout;
|
DrawerLayout drawer = binding.drawerLayout;
|
||||||
NavigationView navigationView = binding.navView;
|
NavigationView navigationView = binding.navView;
|
||||||
// Passing each menu ID as a set of Ids because each
|
// Passing each menu ID as a set of Ids because each
|
||||||
// menu should be considered as top level destinations.
|
// menu should be considered as top level destinations.
|
||||||
mAppBarConfiguration = new AppBarConfiguration.Builder(
|
mAppBarConfiguration = new AppBarConfiguration.Builder(
|
||||||
R.id.nav_home, R.id.nav_gallery, R.id.nav_definicoes)
|
R.id.nav_home, R.id.nav_gallery, R.id.nav_definicoes,
|
||||||
|
R.id.nav_live_games, R.id.nav_clubs)
|
||||||
.setOpenableLayout(drawer)
|
.setOpenableLayout(drawer)
|
||||||
.build();
|
.build();
|
||||||
NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment_content_main);
|
NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment_content_main);
|
||||||
NavigationUI.setupActionBarWithNavController(this, navController, mAppBarConfiguration);
|
NavigationUI.setupActionBarWithNavController(this, navController, mAppBarConfiguration);
|
||||||
NavigationUI.setupWithNavController(navigationView, navController);
|
NavigationUI.setupWithNavController(navigationView, navController);
|
||||||
|
|
||||||
|
// Initialize Gallery Launcher
|
||||||
|
mGetContent = registerForActivityResult(new ActivityResultContracts.GetContent(),
|
||||||
|
uri -> {
|
||||||
|
if (uri != null) {
|
||||||
|
uploadImageToStorage(uri);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Carregar dados do utilizador no menu lateral
|
||||||
|
loadUserDataInNavHeader();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loadUserDataInNavHeader() {
|
||||||
|
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
|
||||||
|
if (user == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
View headerView = binding.navView.getHeaderView(0);
|
||||||
|
TextView textViewName = headerView.findViewById(R.id.textViewName);
|
||||||
|
ImageView imageView = headerView.findViewById(R.id.imageView);
|
||||||
|
|
||||||
|
// Carregar nome
|
||||||
|
if (textViewName != null) {
|
||||||
|
if (user.getDisplayName() != null && !user.getDisplayName().isEmpty()) {
|
||||||
|
textViewName.setText(user.getDisplayName());
|
||||||
|
} else {
|
||||||
|
textViewName.setText("Utilizador");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Carregar foto de perfil
|
||||||
|
if (imageView != null) {
|
||||||
|
imageView.setOnClickListener(v -> showChangeProfilePhotoDialog());
|
||||||
|
if (user.getPhotoUrl() != null) {
|
||||||
|
loadProfileImageInNavHeader(user.getPhotoUrl().toString(), imageView);
|
||||||
|
} else {
|
||||||
|
// Tentar carregar do Storage
|
||||||
|
loadProfileImageFromStorage(imageView);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loadProfileImageInNavHeader(String imageUrl, ImageView imageView) {
|
||||||
|
new Thread(() -> {
|
||||||
|
InputStream input = null;
|
||||||
|
try {
|
||||||
|
java.net.URL url = new java.net.URL(imageUrl);
|
||||||
|
java.net.HttpURLConnection connection = (java.net.HttpURLConnection) url.openConnection();
|
||||||
|
connection.setDoInput(true);
|
||||||
|
connection.connect();
|
||||||
|
input = connection.getInputStream();
|
||||||
|
Bitmap bitmap = BitmapFactory.decodeStream(input);
|
||||||
|
runOnUiThread(() -> {
|
||||||
|
if (bitmap != null && imageView != null) {
|
||||||
|
imageView.setImageBitmap(bitmap);
|
||||||
|
imageView.setScaleType(android.widget.ImageView.ScaleType.CENTER_CROP);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (Exception e) {
|
||||||
|
// Se falhar, tentar carregar do Storage
|
||||||
|
runOnUiThread(() -> loadProfileImageFromStorage(imageView));
|
||||||
|
} finally {
|
||||||
|
if (input != null) {
|
||||||
|
try {
|
||||||
|
input.close();
|
||||||
|
} catch (Exception e) {
|
||||||
|
// Ignorar erro ao fechar
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}).start();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loadProfileImageFromStorage(ImageView imageView) {
|
||||||
|
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
|
||||||
|
if (user == null || imageView == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
com.google.firebase.storage.FirebaseStorage.getInstance()
|
||||||
|
.getReference()
|
||||||
|
.child("profile_images/" + user.getUid() + ".jpg")
|
||||||
|
.getDownloadUrl()
|
||||||
|
.addOnSuccessListener(uri -> {
|
||||||
|
loadProfileImageInNavHeader(uri.toString(), imageView);
|
||||||
|
})
|
||||||
|
.addOnFailureListener(e -> {
|
||||||
|
// Manter imagem padrão
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void showChangeProfilePhotoDialog() {
|
||||||
|
mGetContent.launch("image/*");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void uploadImageToStorage(Uri imageUri) {
|
||||||
|
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
|
||||||
|
if (user == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
StorageReference storageRef = com.google.firebase.storage.FirebaseStorage.getInstance().getReference();
|
||||||
|
StorageReference profileRef = storageRef.child("profile_images/" + user.getUid() + ".jpg");
|
||||||
|
|
||||||
|
Toast.makeText(this, "A carregar imagem...", Toast.LENGTH_SHORT).show();
|
||||||
|
|
||||||
|
profileRef.putFile(imageUri)
|
||||||
|
.addOnSuccessListener(taskSnapshot -> {
|
||||||
|
profileRef.getDownloadUrl().addOnSuccessListener(uri -> {
|
||||||
|
updateUserProfile(uri);
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.addOnFailureListener(e -> {
|
||||||
|
Toast.makeText(MainActivity.this, "Erro ao carregar imagem: " + e.getMessage(), Toast.LENGTH_SHORT)
|
||||||
|
.show();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateUserProfile(Uri photoUri) {
|
||||||
|
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
|
||||||
|
if (user == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
UserProfileChangeRequest profileUpdates = new UserProfileChangeRequest.Builder()
|
||||||
|
.setPhotoUri(photoUri)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
user.updateProfile(profileUpdates)
|
||||||
|
.addOnCompleteListener(task -> {
|
||||||
|
if (task.isSuccessful()) {
|
||||||
|
Toast.makeText(MainActivity.this, "Foto de perfil atualizada!", Toast.LENGTH_SHORT).show();
|
||||||
|
loadUserDataInNavHeader(); // Refresh UI
|
||||||
|
} else {
|
||||||
|
Toast.makeText(MainActivity.this, "Erro ao atualizar perfil.", Toast.LENGTH_SHORT).show();
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onCreateOptionsMenu(Menu menu) {
|
public boolean onCreateOptionsMenu(Menu menu) {
|
||||||
// Inflate the menu; this adds items to the action bar if it is present.
|
// Inflate the menu; this adds items to the action bar if it is present.
|
||||||
// getMenuInflater().inflate(R.menu.main, menu);
|
// getMenuInflater().inflate(R.menu.main, menu);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -63,4 +225,11 @@ public class MainActivity extends AppCompatActivity {
|
|||||||
return NavigationUI.navigateUp(navController, mAppBarConfiguration)
|
return NavigationUI.navigateUp(navController, mAppBarConfiguration)
|
||||||
|| super.onSupportNavigateUp();
|
|| super.onSupportNavigateUp();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onResume() {
|
||||||
|
super.onResume();
|
||||||
|
// Atualizar dados do utilizador quando voltar à activity
|
||||||
|
loadUserDataInNavHeader();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,77 @@
|
|||||||
|
package com.example.vdcscore;
|
||||||
|
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.view.View;
|
||||||
|
import android.widget.Button;
|
||||||
|
import android.widget.ImageButton;
|
||||||
|
import android.widget.TextView;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
|
|
||||||
|
import com.google.android.material.textfield.TextInputEditText;
|
||||||
|
import com.google.firebase.auth.FirebaseAuth;
|
||||||
|
|
||||||
|
public class RecuperarPasswordActivity extends AppCompatActivity {
|
||||||
|
|
||||||
|
private TextInputEditText editEmailRecuperar;
|
||||||
|
private Button btnRecuperar;
|
||||||
|
private ImageButton btnBack;
|
||||||
|
private TextView txtVoltarLogin;
|
||||||
|
private FirebaseAuth mAuth;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
setContentView(R.layout.activity_recuperar_password);
|
||||||
|
|
||||||
|
editEmailRecuperar = findViewById(R.id.editEmailRecuperar);
|
||||||
|
btnRecuperar = findViewById(R.id.btnRecuperar);
|
||||||
|
btnBack = findViewById(R.id.btnBack);
|
||||||
|
txtVoltarLogin = findViewById(R.id.txtVoltarLogin);
|
||||||
|
|
||||||
|
mAuth = FirebaseAuth.getInstance();
|
||||||
|
|
||||||
|
btnRecuperar.setOnClickListener(v -> recuperarPassword());
|
||||||
|
btnBack.setOnClickListener(v -> voltarLogin());
|
||||||
|
txtVoltarLogin.setOnClickListener(v -> voltarLogin());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void recuperarPassword() {
|
||||||
|
String email = editEmailRecuperar.getText().toString().trim();
|
||||||
|
|
||||||
|
if (email.isEmpty()) {
|
||||||
|
Toast.makeText(this, "Por favor, introduza o seu email", Toast.LENGTH_SHORT).show();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!android.util.Patterns.EMAIL_ADDRESS.matcher(email).matches()) {
|
||||||
|
Toast.makeText(this, "Por favor, introduza um email válido", Toast.LENGTH_SHORT).show();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mAuth.sendPasswordResetEmail(email)
|
||||||
|
.addOnCompleteListener(task -> {
|
||||||
|
if (task.isSuccessful()) {
|
||||||
|
Toast.makeText(this,
|
||||||
|
"Email de recuperação enviado! Verifique a sua caixa de entrada.",
|
||||||
|
Toast.LENGTH_LONG).show();
|
||||||
|
voltarLogin();
|
||||||
|
} else {
|
||||||
|
String errorMessage = "Erro ao enviar email de recuperação!";
|
||||||
|
if (task.getException() != null && task.getException().getMessage() != null) {
|
||||||
|
errorMessage = "Erro: " + task.getException().getMessage();
|
||||||
|
}
|
||||||
|
Toast.makeText(this, errorMessage, Toast.LENGTH_LONG).show();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void voltarLogin() {
|
||||||
|
Intent intent = new Intent(RecuperarPasswordActivity.this, LoginActivity.class);
|
||||||
|
startActivity(intent);
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,104 @@
|
|||||||
|
package com.example.vdcscore.data;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
|
||||||
|
import com.example.vdcscore.models.Club;
|
||||||
|
import com.example.vdcscore.models.Jornada;
|
||||||
|
import com.google.android.gms.tasks.OnCompleteListener;
|
||||||
|
import com.google.firebase.database.DataSnapshot;
|
||||||
|
import com.google.firebase.database.DatabaseError;
|
||||||
|
import com.google.firebase.database.DatabaseReference;
|
||||||
|
import com.google.firebase.database.FirebaseDatabase;
|
||||||
|
import com.google.firebase.database.ValueEventListener;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class FirebaseRepository {
|
||||||
|
|
||||||
|
private final DatabaseReference mDatabase;
|
||||||
|
private static FirebaseRepository instance;
|
||||||
|
|
||||||
|
private FirebaseRepository() {
|
||||||
|
mDatabase = FirebaseDatabase.getInstance().getReference();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static synchronized FirebaseRepository getInstance() {
|
||||||
|
if (instance == null) {
|
||||||
|
instance = new FirebaseRepository();
|
||||||
|
}
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Clubs ---
|
||||||
|
|
||||||
|
public void addClub(Club club, OnCompleteListener<Void> onCompleteListener) {
|
||||||
|
String key = String.valueOf(club.getId());
|
||||||
|
if (key == null || key.isEmpty()) {
|
||||||
|
key = mDatabase.child("clubs").push().getKey();
|
||||||
|
club.setId(Integer.parseInt(key));
|
||||||
|
}
|
||||||
|
mDatabase.child("clubs").child(key).setValue(club).addOnCompleteListener(onCompleteListener);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void getClubs(final DataCallback<List<Club>> callback) {
|
||||||
|
mDatabase.child("clubs").addListenerForSingleValueEvent(new ValueEventListener() {
|
||||||
|
@Override
|
||||||
|
public void onDataChange(@NonNull DataSnapshot snapshot) {
|
||||||
|
List<Club> clubs = new ArrayList<>();
|
||||||
|
for (DataSnapshot postSnapshot : snapshot.getChildren()) {
|
||||||
|
Club club = postSnapshot.getValue(Club.class);
|
||||||
|
if (club != null) {
|
||||||
|
club.setId(Integer.parseInt(postSnapshot.getKey()));
|
||||||
|
clubs.add(club);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
callback.onSuccess(clubs);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCancelled(@NonNull DatabaseError error) {
|
||||||
|
callback.onFailure(error.toException());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Jornadas ---
|
||||||
|
|
||||||
|
public void addJornada(Jornada jornada, OnCompleteListener<Void> onCompleteListener) {
|
||||||
|
String key = jornada.getId();
|
||||||
|
if (key == null || key.isEmpty()) {
|
||||||
|
key = mDatabase.child("jornadas").push().getKey();
|
||||||
|
jornada.setId(key);
|
||||||
|
}
|
||||||
|
mDatabase.child("jornadas").child(key).setValue(jornada).addOnCompleteListener(onCompleteListener);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void getJornadas(final DataCallback<List<Jornada>> callback) {
|
||||||
|
mDatabase.child("jornadas").addValueEventListener(new ValueEventListener() {
|
||||||
|
@Override
|
||||||
|
public void onDataChange(@NonNull DataSnapshot snapshot) {
|
||||||
|
List<Jornada> jornadas = new ArrayList<>();
|
||||||
|
for (DataSnapshot postSnapshot : snapshot.getChildren()) {
|
||||||
|
Jornada jornada = postSnapshot.getValue(Jornada.class);
|
||||||
|
if (jornada != null) {
|
||||||
|
jornada.setId(postSnapshot.getKey());
|
||||||
|
jornadas.add(jornada);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
callback.onSuccess(jornadas);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCancelled(@NonNull DatabaseError error) {
|
||||||
|
callback.onFailure(error.toException());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface DataCallback<T> {
|
||||||
|
void onSuccess(T data);
|
||||||
|
|
||||||
|
void onFailure(Exception e);
|
||||||
|
}
|
||||||
|
}
|
||||||
136
app/src/main/java/com/example/vdcscore/models/Club.java
Normal file
@@ -0,0 +1,136 @@
|
|||||||
|
package com.example.vdcscore.models;
|
||||||
|
|
||||||
|
import com.google.firebase.database.PropertyName;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
|
||||||
|
public class Club implements Serializable {
|
||||||
|
@PropertyName("id")
|
||||||
|
private int id;
|
||||||
|
|
||||||
|
@PropertyName("nome")
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@PropertyName("imagem")
|
||||||
|
private String imageUrl;
|
||||||
|
|
||||||
|
@PropertyName("campo")
|
||||||
|
private String stadium;
|
||||||
|
|
||||||
|
@PropertyName("ano fundacao")
|
||||||
|
private int foundationYear;
|
||||||
|
|
||||||
|
@PropertyName("morada")
|
||||||
|
private String address;
|
||||||
|
|
||||||
|
@PropertyName("presidente")
|
||||||
|
private String president;
|
||||||
|
|
||||||
|
@PropertyName("jogadores")
|
||||||
|
private ArrayList<Player> players;
|
||||||
|
|
||||||
|
public Club() {
|
||||||
|
// Default constructor for Firebase
|
||||||
|
players = new ArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Club(int id, String name, String imageUrl, String stadium, int foundationYear, String address,
|
||||||
|
String president) {
|
||||||
|
this.id = id;
|
||||||
|
this.name = name;
|
||||||
|
this.imageUrl = imageUrl;
|
||||||
|
this.stadium = stadium;
|
||||||
|
this.foundationYear = foundationYear;
|
||||||
|
this.address = address;
|
||||||
|
this.president = president;
|
||||||
|
this.players = new ArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
@PropertyName("id")
|
||||||
|
public int getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
@PropertyName("id")
|
||||||
|
public void setId(int id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
@PropertyName("nome")
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@PropertyName("nome")
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@PropertyName("imagem")
|
||||||
|
public String getImageUrl() {
|
||||||
|
return imageUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
@PropertyName("imagem")
|
||||||
|
public void setImageUrl(String imageUrl) {
|
||||||
|
this.imageUrl = imageUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
@PropertyName("campo")
|
||||||
|
public String getStadium() {
|
||||||
|
return stadium;
|
||||||
|
}
|
||||||
|
|
||||||
|
@PropertyName("campo")
|
||||||
|
public void setStadium(String stadium) {
|
||||||
|
this.stadium = stadium;
|
||||||
|
}
|
||||||
|
|
||||||
|
@PropertyName("ano fundacao")
|
||||||
|
public int getFoundationYear() {
|
||||||
|
return foundationYear;
|
||||||
|
}
|
||||||
|
|
||||||
|
@PropertyName("ano fundacao")
|
||||||
|
public void setFoundationYear(int foundationYear) {
|
||||||
|
this.foundationYear = foundationYear;
|
||||||
|
}
|
||||||
|
|
||||||
|
@PropertyName("morada")
|
||||||
|
public String getAddress() {
|
||||||
|
return address;
|
||||||
|
}
|
||||||
|
|
||||||
|
@PropertyName("morada")
|
||||||
|
public void setAddress(String address) {
|
||||||
|
this.address = address;
|
||||||
|
}
|
||||||
|
|
||||||
|
@PropertyName("presidente")
|
||||||
|
public String getPresident() {
|
||||||
|
return president;
|
||||||
|
}
|
||||||
|
|
||||||
|
@PropertyName("presidente")
|
||||||
|
public void setPresident(String president) {
|
||||||
|
this.president = president;
|
||||||
|
}
|
||||||
|
|
||||||
|
@PropertyName("jogadores")
|
||||||
|
public ArrayList<Player> getPlayersMap() {
|
||||||
|
return players;
|
||||||
|
}
|
||||||
|
|
||||||
|
@PropertyName("jogadores")
|
||||||
|
public void setPlayersMap(ArrayList<Player> players) {
|
||||||
|
this.players = players;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Player> getPlayersList() {
|
||||||
|
if (players == null)
|
||||||
|
return new ArrayList<>();
|
||||||
|
return new ArrayList<>(players);
|
||||||
|
}
|
||||||
|
}
|
||||||
102
app/src/main/java/com/example/vdcscore/models/Game.java
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
package com.example.vdcscore.models;
|
||||||
|
|
||||||
|
public class Game {
|
||||||
|
private String id;
|
||||||
|
private String homeTeamId;
|
||||||
|
private String awayTeamId;
|
||||||
|
private String homeTeamName;
|
||||||
|
private String awayTeamName;
|
||||||
|
private int homeScore;
|
||||||
|
private int awayScore;
|
||||||
|
private boolean isFinished;
|
||||||
|
private long timestamp;
|
||||||
|
|
||||||
|
public Game() {
|
||||||
|
// Required for Firebase
|
||||||
|
}
|
||||||
|
|
||||||
|
public Game(String id, String homeTeamId, String awayTeamId, String homeTeamName, String awayTeamName,
|
||||||
|
long timestamp) {
|
||||||
|
this.id = id;
|
||||||
|
this.homeTeamId = homeTeamId;
|
||||||
|
this.awayTeamId = awayTeamId;
|
||||||
|
this.homeTeamName = homeTeamName;
|
||||||
|
this.awayTeamName = awayTeamName;
|
||||||
|
this.timestamp = timestamp;
|
||||||
|
this.isFinished = false;
|
||||||
|
this.homeScore = 0;
|
||||||
|
this.awayScore = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(String id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getHomeTeamId() {
|
||||||
|
return homeTeamId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHomeTeamId(String homeTeamId) {
|
||||||
|
this.homeTeamId = homeTeamId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAwayTeamId() {
|
||||||
|
return awayTeamId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAwayTeamId(String awayTeamId) {
|
||||||
|
this.awayTeamId = awayTeamId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getHomeTeamName() {
|
||||||
|
return homeTeamName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHomeTeamName(String homeTeamName) {
|
||||||
|
this.homeTeamName = homeTeamName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAwayTeamName() {
|
||||||
|
return awayTeamName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAwayTeamName(String awayTeamName) {
|
||||||
|
this.awayTeamName = awayTeamName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getHomeScore() {
|
||||||
|
return homeScore;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHomeScore(int homeScore) {
|
||||||
|
this.homeScore = homeScore;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getAwayScore() {
|
||||||
|
return awayScore;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAwayScore(int awayScore) {
|
||||||
|
this.awayScore = awayScore;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isFinished() {
|
||||||
|
return isFinished;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFinished(boolean finished) {
|
||||||
|
isFinished = finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getTimestamp() {
|
||||||
|
return timestamp;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTimestamp(long timestamp) {
|
||||||
|
this.timestamp = timestamp;
|
||||||
|
}
|
||||||
|
}
|
||||||
55
app/src/main/java/com/example/vdcscore/models/Jornada.java
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
package com.example.vdcscore.models;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class Jornada {
|
||||||
|
private String id;
|
||||||
|
private int number;
|
||||||
|
private List<Game> games;
|
||||||
|
private boolean isCurrent;
|
||||||
|
|
||||||
|
public Jornada() {
|
||||||
|
// Required for Firebase
|
||||||
|
this.games = new ArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Jornada(String id, int number) {
|
||||||
|
this.id = id;
|
||||||
|
this.number = number;
|
||||||
|
this.games = new ArrayList<>();
|
||||||
|
this.isCurrent = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(String id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getNumber() {
|
||||||
|
return number;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNumber(int number) {
|
||||||
|
this.number = number;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Game> getGames() {
|
||||||
|
return games;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setGames(List<Game> games) {
|
||||||
|
this.games = games;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isCurrent() {
|
||||||
|
return isCurrent;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCurrent(boolean current) {
|
||||||
|
isCurrent = current;
|
||||||
|
}
|
||||||
|
}
|
||||||
40
app/src/main/java/com/example/vdcscore/models/Player.java
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
package com.example.vdcscore.models;
|
||||||
|
|
||||||
|
import com.google.firebase.database.PropertyName;
|
||||||
|
|
||||||
|
public class Player {
|
||||||
|
@PropertyName("id")
|
||||||
|
private int id;
|
||||||
|
|
||||||
|
@PropertyName("nome")
|
||||||
|
private String nome;
|
||||||
|
|
||||||
|
public Player() {
|
||||||
|
// Default constructor required for calls to DataSnapshot.getValue(Player.class)
|
||||||
|
}
|
||||||
|
|
||||||
|
public Player(int id, String nome) {
|
||||||
|
this.id = id;
|
||||||
|
this.nome = nome;
|
||||||
|
}
|
||||||
|
|
||||||
|
@PropertyName("id")
|
||||||
|
public int getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
@PropertyName("id")
|
||||||
|
public void setId(int id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
@PropertyName("nome")
|
||||||
|
public String getNome() {
|
||||||
|
return nome;
|
||||||
|
}
|
||||||
|
|
||||||
|
@PropertyName("nome")
|
||||||
|
public void setNome(String nome) {
|
||||||
|
this.nome = nome;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,74 @@
|
|||||||
|
package com.example.vdcscore.ui.clubs;
|
||||||
|
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.TextView;
|
||||||
|
import android.widget.ImageView;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
|
import com.bumptech.glide.Glide;
|
||||||
|
import com.example.vdcscore.R;
|
||||||
|
import com.example.vdcscore.models.Club;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class ClubAdapter extends RecyclerView.Adapter<ClubAdapter.ClubViewHolder> {
|
||||||
|
|
||||||
|
private final List<Club> mClubs;
|
||||||
|
private final OnItemClickListener mListener;
|
||||||
|
|
||||||
|
public interface OnItemClickListener {
|
||||||
|
void onItemClick(Club club);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ClubAdapter(List<Club> clubs, OnItemClickListener listener) {
|
||||||
|
mClubs = clubs;
|
||||||
|
mListener = listener;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
@Override
|
||||||
|
public ClubViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||||
|
View view = LayoutInflater.from(parent.getContext())
|
||||||
|
.inflate(R.layout.item_club, parent, false);
|
||||||
|
return new ClubViewHolder(view);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBindViewHolder(@NonNull ClubViewHolder holder, int position) {
|
||||||
|
Club club = mClubs.get(position);
|
||||||
|
holder.bind(club, mListener);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getItemCount() {
|
||||||
|
return mClubs.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
static class ClubViewHolder extends RecyclerView.ViewHolder {
|
||||||
|
private final TextView name;
|
||||||
|
private final TextView stadium;
|
||||||
|
private final ImageView image_detail_logo;
|
||||||
|
|
||||||
|
public ClubViewHolder(@NonNull View itemView) {
|
||||||
|
super(itemView);
|
||||||
|
name = itemView.findViewById(R.id.text_club_name);
|
||||||
|
stadium = itemView.findViewById(R.id.text_club_stadium);
|
||||||
|
image_detail_logo = itemView.findViewById(R.id.image_club_logo);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void bind(final Club club, final OnItemClickListener listener) {
|
||||||
|
name.setText(club.getName());
|
||||||
|
stadium.setText(club.getStadium());
|
||||||
|
|
||||||
|
Glide.with(itemView.getContext())
|
||||||
|
.load(club.getImageUrl())
|
||||||
|
.into(image_detail_logo);
|
||||||
|
|
||||||
|
itemView.setOnClickListener(v -> listener.onItemClick(club));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,125 @@
|
|||||||
|
package com.example.vdcscore.ui.clubs;
|
||||||
|
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.fragment.app.Fragment;
|
||||||
|
import androidx.navigation.Navigation;
|
||||||
|
|
||||||
|
import com.example.vdcscore.R;
|
||||||
|
import com.example.vdcscore.databinding.FragmentClubDetailBinding;
|
||||||
|
import com.example.vdcscore.models.Club;
|
||||||
|
import com.google.firebase.database.DataSnapshot;
|
||||||
|
import com.google.firebase.database.DatabaseError;
|
||||||
|
import com.google.firebase.database.DatabaseReference;
|
||||||
|
import com.google.firebase.database.FirebaseDatabase;
|
||||||
|
import com.google.firebase.database.ValueEventListener;
|
||||||
|
import com.bumptech.glide.Glide;
|
||||||
|
|
||||||
|
public class ClubDetailFragment extends Fragment {
|
||||||
|
|
||||||
|
private FragmentClubDetailBinding binding;
|
||||||
|
private DatabaseReference mDatabase;
|
||||||
|
private String clubId;
|
||||||
|
private String escalao;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
if (getArguments() != null) {
|
||||||
|
clubId = getArguments().getString("clubId");
|
||||||
|
escalao = getArguments().getString("escalao");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
|
||||||
|
@Nullable Bundle savedInstanceState) {
|
||||||
|
binding = FragmentClubDetailBinding.inflate(inflater, container, false);
|
||||||
|
return binding.getRoot();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
||||||
|
super.onViewCreated(view, savedInstanceState);
|
||||||
|
|
||||||
|
if (getArguments() != null) {
|
||||||
|
Club clubeRecebido = (Club) getArguments().getSerializable("clube_selecionado");
|
||||||
|
|
||||||
|
if (clubeRecebido != null) {
|
||||||
|
// Preencher views diretamente
|
||||||
|
binding.textDetailClubName.setText(clubeRecebido.getName());
|
||||||
|
binding.textDetailFoundation.setText(String.valueOf(clubeRecebido.getFoundationYear()));
|
||||||
|
binding.textDetailPresident.setText(clubeRecebido.getPresident());
|
||||||
|
binding.textDetailAddress.setText(clubeRecebido.getAddress());
|
||||||
|
|
||||||
|
if (getContext() != null) {
|
||||||
|
Glide.with(this)
|
||||||
|
.load(clubeRecebido.getImageUrl())
|
||||||
|
.placeholder(R.mipmap.ic_launcher_round)
|
||||||
|
.error(R.mipmap.ic_launcher)
|
||||||
|
.into(binding.imageDetailLogo);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Configurar o botão para ver jogadores
|
||||||
|
binding.btnPlayers.setOnClickListener(v -> {
|
||||||
|
Bundle bundle = new Bundle();
|
||||||
|
// Passar o 'clube_selecionado' também para a lista de jogadores se necessário,
|
||||||
|
// ou passar o ID como antes se o fragmento de jogadores esperar ID
|
||||||
|
bundle.putString("clubId", String.valueOf(clubeRecebido.getId()));
|
||||||
|
bundle.putString("escalao", escalao);
|
||||||
|
// Se o ClubPlayersFragment esperar "clube_selecionado" tambem, poderiamos
|
||||||
|
// passar:
|
||||||
|
// bundle.putSerializable("clube_selecionado", clubeRecebido);
|
||||||
|
|
||||||
|
Navigation.findNavController(view).navigate(R.id.action_nav_club_detail_to_nav_club_players,
|
||||||
|
bundle);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loadClubDetails() {
|
||||||
|
mDatabase.addListenerForSingleValueEvent(new ValueEventListener() {
|
||||||
|
@Override
|
||||||
|
public void onDataChange(@NonNull DataSnapshot snapshot) {
|
||||||
|
Club club = snapshot.getValue(Club.class);
|
||||||
|
if (club != null) {
|
||||||
|
binding.textDetailClubName.setText(club.getName());
|
||||||
|
binding.textDetailFoundation.setText(String.valueOf(club.getFoundationYear()));
|
||||||
|
binding.textDetailPresident.setText(club.getPresident());
|
||||||
|
binding.textDetailAddress.setText(club.getAddress());
|
||||||
|
// binding.textDetailStadium.setText(club.getStadium()); // Hidden for now
|
||||||
|
|
||||||
|
// binding.imageDetailLogo.setImageResource(R.mipmap.ic_launcher_round);
|
||||||
|
if (getContext() != null) {
|
||||||
|
Glide.with(ClubDetailFragment.this)
|
||||||
|
.load(club.getImageUrl())
|
||||||
|
.placeholder(R.mipmap.ic_launcher_round)
|
||||||
|
.error(R.mipmap.ic_launcher)
|
||||||
|
.into(binding.imageDetailLogo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCancelled(@NonNull DatabaseError error) {
|
||||||
|
if (getContext() != null) {
|
||||||
|
Toast.makeText(getContext(), "Failed to load club details.", Toast.LENGTH_SHORT).show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDestroyView() {
|
||||||
|
super.onDestroyView();
|
||||||
|
binding = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,103 @@
|
|||||||
|
package com.example.vdcscore.ui.clubs;
|
||||||
|
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.fragment.app.Fragment;
|
||||||
|
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||||
|
|
||||||
|
import com.example.vdcscore.databinding.FragmentClubPlayersBinding;
|
||||||
|
import com.example.vdcscore.models.Club;
|
||||||
|
import com.example.vdcscore.models.Player;
|
||||||
|
import com.google.firebase.database.DataSnapshot;
|
||||||
|
import com.google.firebase.database.DatabaseError;
|
||||||
|
import com.google.firebase.database.DatabaseReference;
|
||||||
|
import com.google.firebase.database.FirebaseDatabase;
|
||||||
|
import com.google.firebase.database.ValueEventListener;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class ClubPlayersFragment extends Fragment {
|
||||||
|
|
||||||
|
private FragmentClubPlayersBinding binding;
|
||||||
|
private DatabaseReference mDatabase;
|
||||||
|
private String clubId;
|
||||||
|
private String escalao;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
if (getArguments() != null) {
|
||||||
|
clubId = getArguments().getString("clubId");
|
||||||
|
escalao = getArguments().getString("escalao");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
|
||||||
|
@Nullable Bundle savedInstanceState) {
|
||||||
|
binding = FragmentClubPlayersBinding.inflate(inflater, container, false);
|
||||||
|
return binding.getRoot();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
||||||
|
super.onViewCreated(view, savedInstanceState);
|
||||||
|
|
||||||
|
binding.recyclerPlayersList.setLayoutManager(new LinearLayoutManager(getContext()));
|
||||||
|
binding.progressBarPlayers.setVisibility(View.VISIBLE);
|
||||||
|
|
||||||
|
if (clubId != null && escalao != null) {
|
||||||
|
mDatabase = FirebaseDatabase.getInstance().getReference().child("clubes").child(escalao).child(clubId);
|
||||||
|
loadPlayers();
|
||||||
|
} else {
|
||||||
|
binding.progressBarPlayers.setVisibility(View.GONE);
|
||||||
|
binding.textNoPlayers.setVisibility(View.VISIBLE);
|
||||||
|
binding.textNoPlayers.setText("Erro: Clube ou escalão não identificado.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loadPlayers() {
|
||||||
|
mDatabase.addListenerForSingleValueEvent(new ValueEventListener() {
|
||||||
|
@Override
|
||||||
|
public void onDataChange(@NonNull DataSnapshot snapshot) {
|
||||||
|
Club club = snapshot.getValue(Club.class);
|
||||||
|
binding.progressBarPlayers.setVisibility(View.GONE);
|
||||||
|
|
||||||
|
if (club != null) {
|
||||||
|
List<Player> playerList = club.getPlayersList();
|
||||||
|
if (playerList != null && !playerList.isEmpty()) {
|
||||||
|
PlayerAdapter adapter = new PlayerAdapter(playerList);
|
||||||
|
binding.recyclerPlayersList.setAdapter(adapter);
|
||||||
|
binding.textNoPlayers.setVisibility(View.GONE);
|
||||||
|
} else {
|
||||||
|
binding.textNoPlayers.setVisibility(View.VISIBLE);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
binding.textNoPlayers.setVisibility(View.VISIBLE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCancelled(@NonNull DatabaseError error) {
|
||||||
|
if (getContext() != null) {
|
||||||
|
Toast.makeText(getContext(), "Failed to load players.", Toast.LENGTH_SHORT).show();
|
||||||
|
}
|
||||||
|
binding.progressBarPlayers.setVisibility(View.GONE);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDestroyView() {
|
||||||
|
super.onDestroyView();
|
||||||
|
binding = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,122 @@
|
|||||||
|
package com.example.vdcscore.ui.clubs;
|
||||||
|
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.ProgressBar;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.fragment.app.Fragment;
|
||||||
|
import androidx.navigation.Navigation;
|
||||||
|
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||||
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
|
import com.example.vdcscore.R;
|
||||||
|
import com.example.vdcscore.databinding.FragmentClubsBinding;
|
||||||
|
import com.example.vdcscore.models.Club;
|
||||||
|
import com.google.firebase.database.DataSnapshot;
|
||||||
|
import com.google.firebase.database.DatabaseError;
|
||||||
|
import com.google.firebase.database.DatabaseReference;
|
||||||
|
import com.google.firebase.database.FirebaseDatabase;
|
||||||
|
import com.google.firebase.database.ValueEventListener;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class ClubsFragment extends Fragment {
|
||||||
|
|
||||||
|
private FragmentClubsBinding binding;
|
||||||
|
private DatabaseReference mDatabase;
|
||||||
|
private ValueEventListener mValueEventListener;
|
||||||
|
private static final String TAG = "ClubsFragment";
|
||||||
|
private String currentEscalao = "seniores"; // Default selection
|
||||||
|
|
||||||
|
public View onCreateView(@NonNull LayoutInflater inflater,
|
||||||
|
ViewGroup container, Bundle savedInstanceState) {
|
||||||
|
binding = FragmentClubsBinding.inflate(inflater, container, false);
|
||||||
|
View root = binding.getRoot();
|
||||||
|
|
||||||
|
RecyclerView recyclerView = binding.recyclerClubs;
|
||||||
|
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
|
||||||
|
ProgressBar progressBar = binding.progressBar;
|
||||||
|
|
||||||
|
// Set up toggle listener
|
||||||
|
binding.toggleGroupEscalao.addOnButtonCheckedListener((group, checkedId, isChecked) -> {
|
||||||
|
if (isChecked) {
|
||||||
|
if (checkedId == R.id.btnJuniores) {
|
||||||
|
currentEscalao = "juniores";
|
||||||
|
} else if (checkedId == R.id.btnSeniores) {
|
||||||
|
currentEscalao = "seniores";
|
||||||
|
}
|
||||||
|
loadClubsData(recyclerView, progressBar);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Initial Data Load
|
||||||
|
loadClubsData(recyclerView, progressBar);
|
||||||
|
|
||||||
|
return root;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loadClubsData(RecyclerView recyclerView, ProgressBar progressBar) {
|
||||||
|
progressBar.setVisibility(View.VISIBLE);
|
||||||
|
mDatabase = FirebaseDatabase.getInstance().getReference().child("clubes").child(currentEscalao);
|
||||||
|
|
||||||
|
// Remove previous listener to avoid duplicate data or leaks
|
||||||
|
if (mValueEventListener != null) {
|
||||||
|
mDatabase.removeEventListener(mValueEventListener);
|
||||||
|
}
|
||||||
|
|
||||||
|
mValueEventListener = new ValueEventListener() {
|
||||||
|
@Override
|
||||||
|
public void onDataChange(@NonNull DataSnapshot snapshot) {
|
||||||
|
List<Club> clubs = new ArrayList<>();
|
||||||
|
for (DataSnapshot postSnapshot : snapshot.getChildren()) {
|
||||||
|
Club club = postSnapshot.getValue(Club.class);
|
||||||
|
if (club != null) {
|
||||||
|
clubs.add(club);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ClubAdapter adapter = new ClubAdapter(clubs, club -> {
|
||||||
|
Bundle bundle = new Bundle();
|
||||||
|
bundle.putSerializable("clube_selecionado", club);
|
||||||
|
bundle.putString("escalao", currentEscalao);
|
||||||
|
androidx.navigation.fragment.NavHostFragment.findNavController(ClubsFragment.this)
|
||||||
|
.navigate(R.id.action_nav_clubs_to_nav_club_detail, bundle);
|
||||||
|
});
|
||||||
|
recyclerView.setAdapter(adapter);
|
||||||
|
progressBar.setVisibility(View.GONE);
|
||||||
|
|
||||||
|
if (clubs.isEmpty()) {
|
||||||
|
// Keep UI empty but don't show mock data automatically to avoid confusion
|
||||||
|
// Toast.makeText(getContext(), "No clubs found.", Toast.LENGTH_SHORT).show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCancelled(@NonNull DatabaseError error) {
|
||||||
|
Log.w(TAG, "loadClubs:onCancelled", error.toException());
|
||||||
|
if (getContext() != null) {
|
||||||
|
Toast.makeText(getContext(), "Failed to load clubs.", Toast.LENGTH_SHORT).show();
|
||||||
|
}
|
||||||
|
if (binding != null) {
|
||||||
|
binding.progressBar.setVisibility(View.GONE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
mDatabase.addValueEventListener(mValueEventListener);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDestroyView() {
|
||||||
|
super.onDestroyView();
|
||||||
|
if (mDatabase != null && mValueEventListener != null) {
|
||||||
|
mDatabase.removeEventListener(mValueEventListener);
|
||||||
|
}
|
||||||
|
binding = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
package com.example.vdcscore.ui.clubs;
|
||||||
|
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
|
import com.example.vdcscore.R;
|
||||||
|
import com.example.vdcscore.models.Player;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class PlayerAdapter extends RecyclerView.Adapter<PlayerAdapter.PlayerViewHolder> {
|
||||||
|
|
||||||
|
private final List<Player> mPlayers;
|
||||||
|
|
||||||
|
public PlayerAdapter(List<Player> players) {
|
||||||
|
mPlayers = players;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
@Override
|
||||||
|
public PlayerViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||||
|
View view = LayoutInflater.from(parent.getContext())
|
||||||
|
.inflate(R.layout.item_player, parent, false);
|
||||||
|
return new PlayerViewHolder(view);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBindViewHolder(@NonNull PlayerViewHolder holder, int position) {
|
||||||
|
Player player = mPlayers.get(position);
|
||||||
|
holder.bind(player);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getItemCount() {
|
||||||
|
return mPlayers.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
static class PlayerViewHolder extends RecyclerView.ViewHolder {
|
||||||
|
private final TextView name;
|
||||||
|
|
||||||
|
public PlayerViewHolder(@NonNull View itemView) {
|
||||||
|
super(itemView);
|
||||||
|
name = itemView.findViewById(R.id.text_player_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void bind(Player player) {
|
||||||
|
if (player != null){
|
||||||
|
name.setText(player.getNome());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,26 +1,491 @@
|
|||||||
package com.example.vdcscore.ui.definicoes;
|
package com.example.vdcscore.ui.definicoes;
|
||||||
|
|
||||||
|
import android.Manifest;
|
||||||
|
import android.app.AlertDialog;
|
||||||
|
import android.app.ProgressDialog;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.SharedPreferences;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
|
import android.graphics.Bitmap;
|
||||||
|
import android.graphics.BitmapFactory;
|
||||||
|
import android.net.Uri;
|
||||||
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.provider.MediaStore;
|
||||||
|
import android.view.View;
|
||||||
|
import android.widget.Button;
|
||||||
|
import android.widget.ImageView;
|
||||||
|
import android.widget.TextView;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
import androidx.activity.EdgeToEdge;
|
import androidx.activity.EdgeToEdge;
|
||||||
|
import androidx.activity.result.ActivityResultLauncher;
|
||||||
|
import androidx.activity.result.contract.ActivityResultContracts;
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
import androidx.appcompat.app.AppCompatActivity;
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
|
import androidx.core.content.ContextCompat;
|
||||||
import androidx.core.graphics.Insets;
|
import androidx.core.graphics.Insets;
|
||||||
import androidx.core.view.ViewCompat;
|
import androidx.core.view.ViewCompat;
|
||||||
import androidx.core.view.WindowInsetsCompat;
|
import androidx.core.view.WindowInsetsCompat;
|
||||||
|
|
||||||
|
import com.example.vdcscore.LoginActivity;
|
||||||
import com.example.vdcscore.R;
|
import com.example.vdcscore.R;
|
||||||
|
import com.google.android.material.appbar.MaterialToolbar;
|
||||||
|
import com.google.android.material.textfield.TextInputEditText;
|
||||||
|
import com.google.firebase.auth.FirebaseAuth;
|
||||||
|
import com.google.firebase.auth.FirebaseUser;
|
||||||
|
import com.google.firebase.auth.UserProfileChangeRequest;
|
||||||
|
import com.google.firebase.storage.FirebaseStorage;
|
||||||
|
import com.google.firebase.storage.StorageReference;
|
||||||
|
import com.google.firebase.storage.UploadTask;
|
||||||
|
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.InputStream;
|
||||||
|
|
||||||
public class ContaActivity extends AppCompatActivity {
|
public class ContaActivity extends AppCompatActivity {
|
||||||
|
|
||||||
|
private ImageView imageProfile;
|
||||||
|
private TextInputEditText editName;
|
||||||
|
private TextView textEmail;
|
||||||
|
private Button btnSaveAll;
|
||||||
|
private Button btnChangeEmail;
|
||||||
|
private Button btnChangePassword;
|
||||||
|
private Button btnLogout;
|
||||||
|
private View btnChangePhoto;
|
||||||
|
private View cardImageContainer;
|
||||||
|
|
||||||
|
private FirebaseAuth mAuth;
|
||||||
|
private FirebaseStorage mStorage;
|
||||||
|
private StorageReference storageRef;
|
||||||
|
private ProgressDialog progressDialog;
|
||||||
|
|
||||||
|
private ActivityResultLauncher<Intent> imagePickerLauncher;
|
||||||
|
private ActivityResultLauncher<String> permissionLauncher;
|
||||||
|
private Uri selectedImageUri;
|
||||||
|
|
||||||
|
private static final String PREFS_NAME = "LoginPrefs";
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
EdgeToEdge.enable(this);
|
EdgeToEdge.enable(this);
|
||||||
setContentView(R.layout.activity_conta);
|
setContentView(R.layout.activity_conta);
|
||||||
|
|
||||||
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> {
|
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> {
|
||||||
Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());
|
Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());
|
||||||
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);
|
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);
|
||||||
return insets;
|
return insets;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Inicializar componentes
|
||||||
|
initViews();
|
||||||
|
initFirebase();
|
||||||
|
setupImagePicker();
|
||||||
|
setupPermissionLauncher();
|
||||||
|
loadUserData();
|
||||||
|
setupListeners();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initViews() {
|
||||||
|
MaterialToolbar toolbar = findViewById(R.id.toolbar);
|
||||||
|
setSupportActionBar(toolbar);
|
||||||
|
if (toolbar != null) {
|
||||||
|
toolbar.setNavigationOnClickListener(v -> finish());
|
||||||
|
}
|
||||||
|
|
||||||
|
imageProfile = findViewById(R.id.imageProfile);
|
||||||
|
editName = findViewById(R.id.editName);
|
||||||
|
// In XML it is present as @+id/textEmail inside cardSecurity.
|
||||||
|
textEmail = findViewById(R.id.textEmail);
|
||||||
|
|
||||||
|
btnSaveAll = findViewById(R.id.btnSaveAll);
|
||||||
|
btnChangeEmail = findViewById(R.id.btnChangeEmail);
|
||||||
|
btnChangePassword = findViewById(R.id.btnChangePassword);
|
||||||
|
btnLogout = findViewById(R.id.btnLogout);
|
||||||
|
|
||||||
|
// New FAB for editing photo
|
||||||
|
btnChangePhoto = findViewById(R.id.fabEditPhoto);
|
||||||
|
// Also allow clicking the text
|
||||||
|
View btnChangePhotoText = findViewById(R.id.btnChangePhoto);
|
||||||
|
|
||||||
|
cardImageContainer = findViewById(R.id.cardImageContainer);
|
||||||
|
|
||||||
|
progressDialog = new ProgressDialog(this);
|
||||||
|
progressDialog.setMessage("A processar...");
|
||||||
|
progressDialog.setCancelable(false);
|
||||||
|
|
||||||
|
// Setup listeners here or in setupListeners()
|
||||||
|
if (btnChangePhotoText != null) {
|
||||||
|
btnChangePhotoText.setOnClickListener(v -> openImagePicker());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initFirebase() {
|
||||||
|
mAuth = FirebaseAuth.getInstance();
|
||||||
|
mStorage = FirebaseStorage.getInstance();
|
||||||
|
storageRef = mStorage.getReference();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setupImagePicker() {
|
||||||
|
imagePickerLauncher = registerForActivityResult(
|
||||||
|
new ActivityResultContracts.StartActivityForResult(),
|
||||||
|
result -> {
|
||||||
|
if (result.getResultCode() == RESULT_OK && result.getData() != null) {
|
||||||
|
selectedImageUri = result.getData().getData();
|
||||||
|
if (selectedImageUri != null) {
|
||||||
|
try {
|
||||||
|
InputStream inputStream = getContentResolver().openInputStream(selectedImageUri);
|
||||||
|
if (inputStream != null) {
|
||||||
|
Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
|
||||||
|
inputStream.close();
|
||||||
|
if (bitmap != null) {
|
||||||
|
imageProfile.setImageBitmap(bitmap);
|
||||||
|
// Não fazemos upload até clicar em Gravar
|
||||||
|
} else {
|
||||||
|
Toast.makeText(this, "Erro ao carregar imagem", Toast.LENGTH_SHORT).show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
Toast.makeText(this, "Erro ao carregar imagem: " + e.getMessage(), Toast.LENGTH_SHORT)
|
||||||
|
.show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setupPermissionLauncher() {
|
||||||
|
permissionLauncher = registerForActivityResult(
|
||||||
|
new ActivityResultContracts.RequestPermission(),
|
||||||
|
isGranted -> {
|
||||||
|
if (isGranted) {
|
||||||
|
openImagePicker();
|
||||||
|
} else {
|
||||||
|
Toast.makeText(this, "Permissão necessária para selecionar imagem", Toast.LENGTH_SHORT).show();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loadUserData() {
|
||||||
|
FirebaseUser user = mAuth.getCurrentUser();
|
||||||
|
if (user != null) {
|
||||||
|
// Carregar email
|
||||||
|
if (textEmail != null) {
|
||||||
|
textEmail.setText(user.getEmail() != null ? user.getEmail() : "");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Carregar nome
|
||||||
|
if (editName != null && user.getDisplayName() != null && !user.getDisplayName().isEmpty()) {
|
||||||
|
editName.setText(user.getDisplayName());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Carregar foto de perfil
|
||||||
|
if (user.getPhotoUrl() != null) {
|
||||||
|
loadProfileImage(user.getPhotoUrl().toString());
|
||||||
|
} else {
|
||||||
|
// Tentar carregar do Storage
|
||||||
|
loadProfileImageFromStorage();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Toast.makeText(this, "Utilizador não autenticado", Toast.LENGTH_SHORT).show();
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loadProfileImage(String imageUrl) {
|
||||||
|
new Thread(() -> {
|
||||||
|
InputStream input = null;
|
||||||
|
try {
|
||||||
|
java.net.URL url = new java.net.URL(imageUrl);
|
||||||
|
java.net.HttpURLConnection connection = (java.net.HttpURLConnection) url.openConnection();
|
||||||
|
connection.setDoInput(true);
|
||||||
|
connection.connect();
|
||||||
|
input = connection.getInputStream();
|
||||||
|
Bitmap bitmap = BitmapFactory.decodeStream(input);
|
||||||
|
runOnUiThread(() -> {
|
||||||
|
if (bitmap != null && imageProfile != null) {
|
||||||
|
imageProfile.setImageBitmap(bitmap);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (Exception e) {
|
||||||
|
runOnUiThread(() -> loadProfileImageFromStorage());
|
||||||
|
} finally {
|
||||||
|
if (input != null) {
|
||||||
|
try {
|
||||||
|
input.close();
|
||||||
|
} catch (Exception e) {
|
||||||
|
// Ignorar erro ao fechar
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}).start();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loadProfileImageFromStorage() {
|
||||||
|
FirebaseUser user = mAuth.getCurrentUser();
|
||||||
|
if (user == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
StorageReference profileImageRef = storageRef.child("profile_images/" + user.getUid() + ".jpg");
|
||||||
|
profileImageRef.getDownloadUrl().addOnSuccessListener(uri -> {
|
||||||
|
loadProfileImage(uri.toString());
|
||||||
|
}).addOnFailureListener(e -> {
|
||||||
|
// Foto não encontrada, manter imagem padrão
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setupListeners() {
|
||||||
|
if (btnChangePhoto != null) {
|
||||||
|
btnChangePhoto.setOnClickListener(v -> openImagePicker());
|
||||||
|
}
|
||||||
|
if (cardImageContainer != null) {
|
||||||
|
cardImageContainer.setOnClickListener(v -> openImagePicker());
|
||||||
|
}
|
||||||
|
if (btnSaveAll != null) {
|
||||||
|
btnSaveAll.setOnClickListener(v -> saveAllChanges());
|
||||||
|
}
|
||||||
|
if (btnChangeEmail != null) {
|
||||||
|
btnChangeEmail.setOnClickListener(v -> sendEmailVerificationForEmailChange());
|
||||||
|
}
|
||||||
|
if (btnChangePassword != null) {
|
||||||
|
btnChangePassword.setOnClickListener(v -> sendPasswordResetEmail());
|
||||||
|
}
|
||||||
|
if (btnLogout != null) {
|
||||||
|
btnLogout.setOnClickListener(v -> showLogoutConfirmation());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void openImagePicker() {
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||||
|
Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
|
||||||
|
imagePickerLauncher.launch(intent);
|
||||||
|
} else {
|
||||||
|
String permission = Manifest.permission.READ_EXTERNAL_STORAGE;
|
||||||
|
if (ContextCompat.checkSelfPermission(this, permission) == PackageManager.PERMISSION_GRANTED) {
|
||||||
|
Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
|
||||||
|
imagePickerLauncher.launch(intent);
|
||||||
|
} else {
|
||||||
|
permissionLauncher.launch(permission);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void saveAllChanges() {
|
||||||
|
if (editName == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
String newName = editName.getText().toString().trim();
|
||||||
|
|
||||||
|
if (newName.isEmpty() && selectedImageUri == null) {
|
||||||
|
Toast.makeText(this, "Nenhuma alteração a guardar", Toast.LENGTH_SHORT).show();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
FirebaseUser user = mAuth.getCurrentUser();
|
||||||
|
if (user == null) {
|
||||||
|
Toast.makeText(this, "Utilizador não autenticado", Toast.LENGTH_SHORT).show();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
progressDialog.show();
|
||||||
|
|
||||||
|
// Se tiver foto nova, primeiro faz upload
|
||||||
|
if (selectedImageUri != null) {
|
||||||
|
uploadNewProfileImageAndSaveName(user, newName);
|
||||||
|
} else {
|
||||||
|
// Só muda o nome
|
||||||
|
saveNameOnly(user, newName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void saveNameOnly(FirebaseUser user, String newName) {
|
||||||
|
if (newName.isEmpty()) {
|
||||||
|
progressDialog.dismiss();
|
||||||
|
return; // Se não houver nome para trocar nem imagem, já barrámos em saveAllChanges.
|
||||||
|
}
|
||||||
|
|
||||||
|
UserProfileChangeRequest profileUpdates = new UserProfileChangeRequest.Builder()
|
||||||
|
.setDisplayName(newName)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
user.updateProfile(profileUpdates).addOnCompleteListener(task -> {
|
||||||
|
progressDialog.dismiss();
|
||||||
|
if (task.isSuccessful()) {
|
||||||
|
Toast.makeText(this, "Alterações guardadas com sucesso!", Toast.LENGTH_SHORT).show();
|
||||||
|
} else {
|
||||||
|
Toast.makeText(this, "Erro ao guardar alterações: " +
|
||||||
|
(task.getException() != null ? task.getException().getMessage() : "Erro desconhecido"),
|
||||||
|
Toast.LENGTH_SHORT).show();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void uploadNewProfileImageAndSaveName(FirebaseUser user, String newName) {
|
||||||
|
InputStream inputStream = null;
|
||||||
|
try {
|
||||||
|
inputStream = getContentResolver().openInputStream(selectedImageUri);
|
||||||
|
if (inputStream == null) {
|
||||||
|
progressDialog.dismiss();
|
||||||
|
Toast.makeText(this, "Erro ao abrir imagem", Toast.LENGTH_SHORT).show();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
|
||||||
|
if (bitmap == null) {
|
||||||
|
progressDialog.dismiss();
|
||||||
|
Toast.makeText(this, "Erro ao processar imagem", Toast.LENGTH_SHORT).show();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Redimensionar
|
||||||
|
int maxSize = 1024;
|
||||||
|
if (bitmap.getWidth() > maxSize || bitmap.getHeight() > maxSize) {
|
||||||
|
float scale = Math.min((float) maxSize / bitmap.getWidth(), (float) maxSize / bitmap.getHeight());
|
||||||
|
int newWidth = Math.round(bitmap.getWidth() * scale);
|
||||||
|
int newHeight = Math.round(bitmap.getHeight() * scale);
|
||||||
|
bitmap = Bitmap.createScaledBitmap(bitmap, newWidth, newHeight, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||||
|
bitmap.compress(Bitmap.CompressFormat.JPEG, 80, baos);
|
||||||
|
byte[] imageData = baos.toByteArray();
|
||||||
|
|
||||||
|
StorageReference profileImageRef = storageRef.child("profile_images/" + user.getUid() + ".jpg");
|
||||||
|
UploadTask uploadTask = profileImageRef.putBytes(imageData);
|
||||||
|
|
||||||
|
uploadTask.addOnSuccessListener(taskSnapshot -> {
|
||||||
|
profileImageRef.getDownloadUrl().addOnSuccessListener(uri -> {
|
||||||
|
|
||||||
|
UserProfileChangeRequest.Builder builder = new UserProfileChangeRequest.Builder();
|
||||||
|
builder.setPhotoUri(uri);
|
||||||
|
if (!newName.isEmpty()) {
|
||||||
|
builder.setDisplayName(newName);
|
||||||
|
}
|
||||||
|
UserProfileChangeRequest profileUpdates = builder.build();
|
||||||
|
|
||||||
|
user.updateProfile(profileUpdates).addOnCompleteListener(task -> {
|
||||||
|
progressDialog.dismiss();
|
||||||
|
if (task.isSuccessful()) {
|
||||||
|
Toast.makeText(this, "As definições foram guardadas!", Toast.LENGTH_SHORT).show();
|
||||||
|
loadProfileImage(uri.toString());
|
||||||
|
selectedImageUri = null; // reset
|
||||||
|
} else {
|
||||||
|
Toast.makeText(this, "Erro ao atualizar perfil", Toast.LENGTH_SHORT).show();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}).addOnFailureListener(e -> {
|
||||||
|
progressDialog.dismiss();
|
||||||
|
Toast.makeText(this, "Erro ao obter URL: " + e.getMessage(), Toast.LENGTH_SHORT).show();
|
||||||
|
});
|
||||||
|
}).addOnFailureListener(e -> {
|
||||||
|
progressDialog.dismiss();
|
||||||
|
Toast.makeText(this, "Erro ao fazer upload: " + e.getMessage(), Toast.LENGTH_SHORT).show();
|
||||||
|
});
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
progressDialog.dismiss();
|
||||||
|
Toast.makeText(this, "Erro: " + e.getMessage(), Toast.LENGTH_SHORT).show();
|
||||||
|
} finally {
|
||||||
|
if (inputStream != null) {
|
||||||
|
try {
|
||||||
|
inputStream.close();
|
||||||
|
} catch (Exception e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void sendPasswordResetEmail() {
|
||||||
|
FirebaseUser user = mAuth.getCurrentUser();
|
||||||
|
if (user == null || user.getEmail() == null) {
|
||||||
|
Toast.makeText(this, "Utilizador não autenticado", Toast.LENGTH_SHORT).show();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
progressDialog.show();
|
||||||
|
|
||||||
|
mAuth.sendPasswordResetEmail(user.getEmail())
|
||||||
|
.addOnCompleteListener(task -> {
|
||||||
|
progressDialog.dismiss();
|
||||||
|
if (task.isSuccessful()) {
|
||||||
|
Toast.makeText(this,
|
||||||
|
"Email de alteração de password enviado! Verifique a sua caixa de entrada.",
|
||||||
|
Toast.LENGTH_LONG).show();
|
||||||
|
} else {
|
||||||
|
String errorMessage = "Erro ao enviar email!";
|
||||||
|
if (task.getException() != null && task.getException().getMessage() != null) {
|
||||||
|
errorMessage = "Erro: " + task.getException().getMessage();
|
||||||
|
}
|
||||||
|
Toast.makeText(this, errorMessage, Toast.LENGTH_LONG).show();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void sendEmailVerificationForEmailChange() {
|
||||||
|
FirebaseUser user = mAuth.getCurrentUser();
|
||||||
|
if (user == null || user.getEmail() == null) {
|
||||||
|
Toast.makeText(this, "Utilizador não autenticado", Toast.LENGTH_SHORT).show();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
progressDialog.show();
|
||||||
|
|
||||||
|
// Enviar email de verificação para alterar email
|
||||||
|
user.sendEmailVerification()
|
||||||
|
.addOnCompleteListener(task -> {
|
||||||
|
progressDialog.dismiss();
|
||||||
|
if (task.isSuccessful()) {
|
||||||
|
Toast.makeText(this,
|
||||||
|
"Email de verificação enviado! Verifique a sua caixa de entrada para alterar o email.",
|
||||||
|
Toast.LENGTH_LONG).show();
|
||||||
|
} else {
|
||||||
|
// Se não conseguir enviar email de verificação, enviar email de reset de
|
||||||
|
// password
|
||||||
|
// que pode ser usado para alterar o email através do Firebase Console
|
||||||
|
mAuth.sendPasswordResetEmail(user.getEmail())
|
||||||
|
.addOnCompleteListener(resetTask -> {
|
||||||
|
if (resetTask.isSuccessful()) {
|
||||||
|
Toast.makeText(this,
|
||||||
|
"Email enviado! Verifique a sua caixa de entrada para instruções de alteração.",
|
||||||
|
Toast.LENGTH_LONG).show();
|
||||||
|
} else {
|
||||||
|
String errorMessage = "Erro ao enviar email!";
|
||||||
|
if (resetTask.getException() != null
|
||||||
|
&& resetTask.getException().getMessage() != null) {
|
||||||
|
errorMessage = "Erro: " + resetTask.getException().getMessage();
|
||||||
|
}
|
||||||
|
Toast.makeText(this, errorMessage, Toast.LENGTH_LONG).show();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void showLogoutConfirmation() {
|
||||||
|
new AlertDialog.Builder(this)
|
||||||
|
.setTitle("Terminar Sessão")
|
||||||
|
.setMessage("Tem a certeza que deseja terminar a sessão?")
|
||||||
|
.setPositiveButton("Sim", (dialog, which) -> logoutUser())
|
||||||
|
.setNegativeButton("Cancelar", null)
|
||||||
|
.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void logoutUser() {
|
||||||
|
// Limpar credenciais guardadas
|
||||||
|
SharedPreferences prefs = getSharedPreferences(PREFS_NAME, MODE_PRIVATE);
|
||||||
|
SharedPreferences.Editor editor = prefs.edit();
|
||||||
|
editor.clear();
|
||||||
|
editor.apply();
|
||||||
|
|
||||||
|
// Fazer logout do Firebase
|
||||||
|
mAuth.signOut();
|
||||||
|
|
||||||
|
Toast.makeText(this, "Sessão terminada", Toast.LENGTH_SHORT).show();
|
||||||
|
|
||||||
|
// Voltar para o login
|
||||||
|
Intent intent = new Intent(ContaActivity.this, LoginActivity.class);
|
||||||
|
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
|
||||||
|
startActivity(intent);
|
||||||
|
finish();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -30,7 +30,8 @@ public class DefinicoesFragment extends Fragment {
|
|||||||
setupUi();
|
setupUi();
|
||||||
return binding.getRoot();
|
return binding.getRoot();
|
||||||
}
|
}
|
||||||
//teste
|
|
||||||
|
// teste
|
||||||
private void setupUi() {
|
private void setupUi() {
|
||||||
binding.cardConta.setOnClickListener(new View.OnClickListener() {
|
binding.cardConta.setOnClickListener(new View.OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
@@ -44,14 +45,35 @@ public class DefinicoesFragment extends Fragment {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
binding.switchNotifications
|
||||||
binding.switchNotifications.setOnCheckedChangeListener((buttonView, isChecked) ->
|
.setOnCheckedChangeListener((buttonView, isChecked) -> binding.textNotificationsStatus.setText(
|
||||||
binding.textNotificationsStatus.setText(
|
|
||||||
isChecked ? "Ativadas" : "Desativadas"));
|
isChecked ? "Ativadas" : "Desativadas"));
|
||||||
|
|
||||||
binding.switchDarkMode.setOnCheckedChangeListener((buttonView, isChecked) ->
|
// Obter SharedPreferences
|
||||||
binding.textDarkModeStatus.setText(
|
android.content.SharedPreferences prefs = requireActivity().getSharedPreferences("SettingsPrefs",
|
||||||
isChecked ? "Ativo" : "Inativo"));
|
android.content.Context.MODE_PRIVATE);
|
||||||
|
boolean isDarkMode = prefs.getBoolean("dark_mode", false);
|
||||||
|
|
||||||
|
binding.switchDarkMode.setChecked(isDarkMode);
|
||||||
|
binding.textDarkModeStatus.setText(isDarkMode ? "Ativo" : "Inativo");
|
||||||
|
|
||||||
|
binding.switchDarkMode.setOnCheckedChangeListener((buttonView, isChecked) -> {
|
||||||
|
binding.textDarkModeStatus.setText(isChecked ? "Ativo" : "Inativo");
|
||||||
|
|
||||||
|
// Guardar preferência
|
||||||
|
android.content.SharedPreferences.Editor editor = prefs.edit();
|
||||||
|
editor.putBoolean("dark_mode", isChecked);
|
||||||
|
editor.apply();
|
||||||
|
|
||||||
|
// Aplicar modo escuro
|
||||||
|
if (isChecked) {
|
||||||
|
androidx.appcompat.app.AppCompatDelegate
|
||||||
|
.setDefaultNightMode(androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_YES);
|
||||||
|
} else {
|
||||||
|
androidx.appcompat.app.AppCompatDelegate
|
||||||
|
.setDefaultNightMode(androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_NO);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
binding.btnOpenSystemSettings.setOnClickListener(v -> {
|
binding.btnOpenSystemSettings.setOnClickListener(v -> {
|
||||||
Intent intent = new Intent(Settings.ACTION_SETTINGS);
|
Intent intent = new Intent(Settings.ACTION_SETTINGS);
|
||||||
@@ -66,4 +88,3 @@ public class DefinicoesFragment extends Fragment {
|
|||||||
binding = null;
|
binding = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,31 +4,82 @@ import android.os.Bundle;
|
|||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.TextView;
|
import android.widget.Toast;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.fragment.app.Fragment;
|
import androidx.fragment.app.Fragment;
|
||||||
import androidx.lifecycle.ViewModelProvider;
|
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||||
|
|
||||||
import com.example.vdcscore.databinding.FragmentGalleryBinding;
|
import com.example.vdcscore.databinding.FragmentGalleryBinding;
|
||||||
|
import com.google.firebase.database.DataSnapshot;
|
||||||
|
import com.google.firebase.database.DatabaseError;
|
||||||
|
import com.google.firebase.database.DatabaseReference;
|
||||||
|
import com.google.firebase.database.FirebaseDatabase;
|
||||||
|
import com.google.firebase.database.ValueEventListener;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public class GalleryFragment extends Fragment {
|
public class GalleryFragment extends Fragment {
|
||||||
|
|
||||||
private FragmentGalleryBinding binding;
|
private FragmentGalleryBinding binding;
|
||||||
|
private MatchdaysAdapter adapter;
|
||||||
|
private DatabaseReference mDatabase;
|
||||||
|
|
||||||
public View onCreateView(@NonNull LayoutInflater inflater,
|
public View onCreateView(@NonNull LayoutInflater inflater,
|
||||||
ViewGroup container, Bundle savedInstanceState) {
|
ViewGroup container, Bundle savedInstanceState) {
|
||||||
GalleryViewModel galleryViewModel =
|
|
||||||
new ViewModelProvider(this).get(GalleryViewModel.class);
|
|
||||||
|
|
||||||
binding = FragmentGalleryBinding.inflate(inflater, container, false);
|
binding = FragmentGalleryBinding.inflate(inflater, container, false);
|
||||||
View root = binding.getRoot();
|
View root = binding.getRoot();
|
||||||
|
|
||||||
final TextView textView = binding.textGallery;
|
// Initialize RecyclerView
|
||||||
galleryViewModel.getText().observe(getViewLifecycleOwner(), textView::setText);
|
adapter = new MatchdaysAdapter();
|
||||||
|
binding.recyclerMatchdays.setLayoutManager(new LinearLayoutManager(getContext()));
|
||||||
|
binding.recyclerMatchdays.setAdapter(adapter);
|
||||||
|
|
||||||
|
// Initialize Firebase
|
||||||
|
mDatabase = FirebaseDatabase.getInstance().getReference("matchdays");
|
||||||
|
|
||||||
|
// Fetch Data
|
||||||
|
fetchMatchdays();
|
||||||
|
|
||||||
return root;
|
return root;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void fetchMatchdays() {
|
||||||
|
mDatabase.addValueEventListener(new ValueEventListener() {
|
||||||
|
@Override
|
||||||
|
public void onDataChange(@NonNull DataSnapshot snapshot) {
|
||||||
|
List<Matchday> matchdays = new ArrayList<>();
|
||||||
|
for (DataSnapshot postSnapshot : snapshot.getChildren()) {
|
||||||
|
Matchday matchday = new Matchday();
|
||||||
|
matchday.setId(postSnapshot.getKey());
|
||||||
|
matchday.setName(postSnapshot.child("name").getValue(String.class));
|
||||||
|
|
||||||
|
List<Match> matches = new ArrayList<>();
|
||||||
|
for (DataSnapshot matchSnapshot : postSnapshot.child("matches").getChildren()) {
|
||||||
|
Match match = matchSnapshot.getValue(Match.class);
|
||||||
|
if (match != null) {
|
||||||
|
match.setId(matchSnapshot.getKey());
|
||||||
|
matches.add(match);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
matchday.setMatches(matches);
|
||||||
|
matchdays.add(matchday);
|
||||||
|
}
|
||||||
|
adapter.setMatchdays(matchdays);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCancelled(@NonNull DatabaseError error) {
|
||||||
|
if (getContext() != null) {
|
||||||
|
Toast.makeText(getContext(), "Erro ao carregar jornadas: " + error.getMessage(), Toast.LENGTH_SHORT)
|
||||||
|
.show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDestroyView() {
|
public void onDestroyView() {
|
||||||
super.onDestroyView();
|
super.onDestroyView();
|
||||||
|
|||||||
88
app/src/main/java/com/example/vdcscore/ui/gallery/Match.java
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
package com.example.vdcscore.ui.gallery;
|
||||||
|
|
||||||
|
public class Match {
|
||||||
|
private String id;
|
||||||
|
private String homeTeam;
|
||||||
|
private String awayTeam;
|
||||||
|
private int homeScore;
|
||||||
|
private int awayScore;
|
||||||
|
private String date;
|
||||||
|
private String time;
|
||||||
|
private String status; // "Scheduled", "Finished", "Live"
|
||||||
|
|
||||||
|
public Match() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public Match(String homeTeam, String awayTeam, String date, String time) {
|
||||||
|
this.homeTeam = homeTeam;
|
||||||
|
this.awayTeam = awayTeam;
|
||||||
|
this.date = date;
|
||||||
|
this.time = time;
|
||||||
|
this.status = "Scheduled";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Getters and Setters
|
||||||
|
public String getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(String id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getHomeTeam() {
|
||||||
|
return homeTeam;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHomeTeam(String homeTeam) {
|
||||||
|
this.homeTeam = homeTeam;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAwayTeam() {
|
||||||
|
return awayTeam;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAwayTeam(String awayTeam) {
|
||||||
|
this.awayTeam = awayTeam;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getHomeScore() {
|
||||||
|
return homeScore;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHomeScore(int homeScore) {
|
||||||
|
this.homeScore = homeScore;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getAwayScore() {
|
||||||
|
return awayScore;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAwayScore(int awayScore) {
|
||||||
|
this.awayScore = awayScore;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDate() {
|
||||||
|
return date;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDate(String date) {
|
||||||
|
this.date = date;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTime() {
|
||||||
|
return time;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTime(String time) {
|
||||||
|
this.time = time;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getStatus() {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStatus(String status) {
|
||||||
|
this.status = status;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
package com.example.vdcscore.ui.gallery;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class Matchday {
|
||||||
|
private String id;
|
||||||
|
private String name; // e.g., "Jornada 1"
|
||||||
|
private List<Match> matches;
|
||||||
|
|
||||||
|
public Matchday() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public Matchday(String name, List<Match> matches) {
|
||||||
|
this.name = name;
|
||||||
|
this.matches = matches;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(String id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Match> getMatches() {
|
||||||
|
return matches;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMatches(List<Match> matches) {
|
||||||
|
this.matches = matches;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
package com.example.vdcscore.ui.gallery;
|
||||||
|
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||||
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
|
import com.example.vdcscore.R;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class MatchdaysAdapter extends RecyclerView.Adapter<MatchdaysAdapter.ViewHolder> {
|
||||||
|
|
||||||
|
private List<Matchday> matchdays = new ArrayList<>();
|
||||||
|
private RecyclerView.RecycledViewPool viewPool = new RecyclerView.RecycledViewPool();
|
||||||
|
|
||||||
|
public void setMatchdays(List<Matchday> matchdays) {
|
||||||
|
this.matchdays = matchdays;
|
||||||
|
notifyDataSetChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
@Override
|
||||||
|
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||||
|
View view = LayoutInflater.from(parent.getContext())
|
||||||
|
.inflate(R.layout.item_matchday, parent, false);
|
||||||
|
return new ViewHolder(view);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
|
||||||
|
Matchday matchday = matchdays.get(position);
|
||||||
|
holder.textName.setText(matchday.getName());
|
||||||
|
|
||||||
|
// Setup nested RecyclerView
|
||||||
|
LinearLayoutManager layoutManager = new LinearLayoutManager(
|
||||||
|
holder.recyclerMatches.getContext(),
|
||||||
|
LinearLayoutManager.VERTICAL,
|
||||||
|
false);
|
||||||
|
layoutManager.setInitialPrefetchItemCount(matchday.getMatches().size());
|
||||||
|
|
||||||
|
MatchesAdapter matchesAdapter = new MatchesAdapter(matchday.getMatches());
|
||||||
|
holder.recyclerMatches.setLayoutManager(layoutManager);
|
||||||
|
holder.recyclerMatches.setAdapter(matchesAdapter);
|
||||||
|
holder.recyclerMatches.setRecycledViewPool(viewPool);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getItemCount() {
|
||||||
|
return matchdays.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class ViewHolder extends RecyclerView.ViewHolder {
|
||||||
|
public final TextView textName;
|
||||||
|
public final RecyclerView recyclerMatches;
|
||||||
|
|
||||||
|
public ViewHolder(View view) {
|
||||||
|
super(view);
|
||||||
|
textName = view.findViewById(R.id.text_matchday_name);
|
||||||
|
recyclerMatches = view.findViewById(R.id.recycler_matches);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,65 @@
|
|||||||
|
package com.example.vdcscore.ui.gallery;
|
||||||
|
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
|
import com.example.vdcscore.R;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class MatchesAdapter extends RecyclerView.Adapter<MatchesAdapter.ViewHolder> {
|
||||||
|
|
||||||
|
private List<Match> matches;
|
||||||
|
|
||||||
|
public MatchesAdapter(List<Match> matches) {
|
||||||
|
this.matches = matches;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
@Override
|
||||||
|
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||||
|
View view = LayoutInflater.from(parent.getContext())
|
||||||
|
.inflate(R.layout.item_match, parent, false);
|
||||||
|
return new ViewHolder(view);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
|
||||||
|
Match match = matches.get(position);
|
||||||
|
holder.textHomeTeam.setText(match.getHomeTeam());
|
||||||
|
holder.textAwayTeam.setText(match.getAwayTeam());
|
||||||
|
|
||||||
|
if ("Finished".equals(match.getStatus())) {
|
||||||
|
holder.textScore.setText(match.getHomeScore() + " - " + match.getAwayScore());
|
||||||
|
holder.textTime.setText("Final");
|
||||||
|
} else {
|
||||||
|
holder.textScore.setText("Vs");
|
||||||
|
holder.textTime.setText(match.getTime());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getItemCount() {
|
||||||
|
return matches == null ? 0 : matches.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class ViewHolder extends RecyclerView.ViewHolder {
|
||||||
|
public final TextView textHomeTeam;
|
||||||
|
public final TextView textAwayTeam;
|
||||||
|
public final TextView textScore;
|
||||||
|
public final TextView textTime;
|
||||||
|
|
||||||
|
public ViewHolder(View view) {
|
||||||
|
super(view);
|
||||||
|
textHomeTeam = view.findViewById(R.id.text_home_team);
|
||||||
|
textAwayTeam = view.findViewById(R.id.text_away_team);
|
||||||
|
textScore = view.findViewById(R.id.text_score);
|
||||||
|
textTime = view.findViewById(R.id.text_time);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,31 +4,90 @@ import android.os.Bundle;
|
|||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.TextView;
|
import android.widget.Toast;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.fragment.app.Fragment;
|
import androidx.fragment.app.Fragment;
|
||||||
import androidx.lifecycle.ViewModelProvider;
|
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||||
|
|
||||||
import com.example.vdcscore.databinding.FragmentHomeBinding;
|
import com.example.vdcscore.databinding.FragmentHomeBinding;
|
||||||
|
import com.google.firebase.database.DataSnapshot;
|
||||||
|
import com.google.firebase.database.DatabaseError;
|
||||||
|
import com.google.firebase.database.DatabaseReference;
|
||||||
|
import com.google.firebase.database.FirebaseDatabase;
|
||||||
|
import com.google.firebase.database.ValueEventListener;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public class HomeFragment extends Fragment {
|
public class HomeFragment extends Fragment {
|
||||||
|
|
||||||
private FragmentHomeBinding binding;
|
private FragmentHomeBinding binding;
|
||||||
|
private StandingsAdapter adapter;
|
||||||
|
private DatabaseReference mDatabase;
|
||||||
|
|
||||||
public View onCreateView(@NonNull LayoutInflater inflater,
|
public View onCreateView(@NonNull LayoutInflater inflater,
|
||||||
ViewGroup container, Bundle savedInstanceState) {
|
ViewGroup container, Bundle savedInstanceState) {
|
||||||
HomeViewModel homeViewModel =
|
|
||||||
new ViewModelProvider(this).get(HomeViewModel.class);
|
|
||||||
|
|
||||||
binding = FragmentHomeBinding.inflate(inflater, container, false);
|
binding = FragmentHomeBinding.inflate(inflater, container, false);
|
||||||
View root = binding.getRoot();
|
View root = binding.getRoot();
|
||||||
|
|
||||||
final TextView textView = binding.textHome;
|
// Initialize RecyclerView
|
||||||
homeViewModel.getText().observe(getViewLifecycleOwner(), textView::setText);
|
adapter = new StandingsAdapter();
|
||||||
|
binding.recyclerStandings.setLayoutManager(new LinearLayoutManager(getContext()));
|
||||||
|
binding.recyclerStandings.setAdapter(adapter);
|
||||||
|
|
||||||
|
// Initialize Firebase
|
||||||
|
mDatabase = FirebaseDatabase.getInstance().getReference("standings");
|
||||||
|
|
||||||
|
// Fetch Data
|
||||||
|
fetchStandings();
|
||||||
|
|
||||||
return root;
|
return root;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void fetchStandings() {
|
||||||
|
mDatabase.addValueEventListener(new ValueEventListener() {
|
||||||
|
@Override
|
||||||
|
public void onDataChange(@NonNull DataSnapshot snapshot) {
|
||||||
|
List<Team> teams = new ArrayList<>();
|
||||||
|
for (DataSnapshot postSnapshot : snapshot.getChildren()) {
|
||||||
|
Team team = postSnapshot.getValue(Team.class);
|
||||||
|
if (team != null) {
|
||||||
|
// If ID is missing, set it from the key
|
||||||
|
if (team.getId() == null) {
|
||||||
|
team.setId(postSnapshot.getKey());
|
||||||
|
}
|
||||||
|
teams.add(team);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sort by Points (Descending), then Goal Difference, then Goals For
|
||||||
|
Collections.sort(teams, new Comparator<Team>() {
|
||||||
|
@Override
|
||||||
|
public int compare(Team t1, Team t2) {
|
||||||
|
if (t1.getPoints() != t2.getPoints()) {
|
||||||
|
return t2.getPoints() - t1.getPoints(); // Descending points
|
||||||
|
}
|
||||||
|
return t2.getGoalDifference() - t1.getGoalDifference(); // Descending GD
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
adapter.setTeams(teams);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCancelled(@NonNull DatabaseError error) {
|
||||||
|
if (getContext() != null) {
|
||||||
|
Toast.makeText(getContext(), "Erro ao carregar classificação: " + error.getMessage(),
|
||||||
|
Toast.LENGTH_SHORT).show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDestroyView() {
|
public void onDestroyView() {
|
||||||
super.onDestroyView();
|
super.onDestroyView();
|
||||||
|
|||||||
@@ -0,0 +1,66 @@
|
|||||||
|
package com.example.vdcscore.ui.home;
|
||||||
|
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
|
import com.example.vdcscore.R;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class StandingsAdapter extends RecyclerView.Adapter<StandingsAdapter.ViewHolder> {
|
||||||
|
|
||||||
|
private List<Team> mTeams;
|
||||||
|
|
||||||
|
public StandingsAdapter() {
|
||||||
|
this.mTeams = new ArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTeams(List<Team> teams) {
|
||||||
|
this.mTeams = teams;
|
||||||
|
notifyDataSetChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
@Override
|
||||||
|
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||||
|
View view = LayoutInflater.from(parent.getContext())
|
||||||
|
.inflate(R.layout.item_standing, parent, false);
|
||||||
|
return new ViewHolder(view);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
|
||||||
|
Team team = mTeams.get(position);
|
||||||
|
|
||||||
|
holder.textPosition.setText(String.valueOf(position + 1));
|
||||||
|
holder.textTeamName.setText(team.getName());
|
||||||
|
holder.textPlayed.setText(String.valueOf(team.getPlayed()));
|
||||||
|
holder.textPoints.setText(String.valueOf(team.getPoints()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getItemCount() {
|
||||||
|
return mTeams.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class ViewHolder extends RecyclerView.ViewHolder {
|
||||||
|
public final TextView textPosition;
|
||||||
|
public final TextView textTeamName;
|
||||||
|
public final TextView textPlayed;
|
||||||
|
public final TextView textPoints;
|
||||||
|
|
||||||
|
public ViewHolder(View view) {
|
||||||
|
super(view);
|
||||||
|
textPosition = view.findViewById(R.id.text_position);
|
||||||
|
textTeamName = view.findViewById(R.id.text_team_name);
|
||||||
|
textPlayed = view.findViewById(R.id.text_played);
|
||||||
|
textPoints = view.findViewById(R.id.text_points);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
106
app/src/main/java/com/example/vdcscore/ui/home/Team.java
Normal file
@@ -0,0 +1,106 @@
|
|||||||
|
package com.example.vdcscore.ui.home;
|
||||||
|
|
||||||
|
public class Team {
|
||||||
|
private String id;
|
||||||
|
private String name;
|
||||||
|
private int points;
|
||||||
|
private int played;
|
||||||
|
private int won;
|
||||||
|
private int drawn;
|
||||||
|
private int lost;
|
||||||
|
private int goalsFor;
|
||||||
|
private int goalsAgainst;
|
||||||
|
private int goalDifference;
|
||||||
|
|
||||||
|
public Team() {
|
||||||
|
// Required empty constructor for Firebase
|
||||||
|
}
|
||||||
|
|
||||||
|
public Team(String id, String name, int points, int played) {
|
||||||
|
this.id = id;
|
||||||
|
this.name = name;
|
||||||
|
this.points = points;
|
||||||
|
this.played = played;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Getters and Setters
|
||||||
|
public String getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(String id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getPoints() {
|
||||||
|
return points;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPoints(int points) {
|
||||||
|
this.points = points;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getPlayed() {
|
||||||
|
return played;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPlayed(int played) {
|
||||||
|
this.played = played;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getWon() {
|
||||||
|
return won;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setWon(int won) {
|
||||||
|
this.won = won;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getDrawn() {
|
||||||
|
return drawn;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDrawn(int drawn) {
|
||||||
|
this.drawn = drawn;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getLost() {
|
||||||
|
return lost;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLost(int lost) {
|
||||||
|
this.lost = lost;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getGoalsFor() {
|
||||||
|
return goalsFor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setGoalsFor(int goalsFor) {
|
||||||
|
this.goalsFor = goalsFor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getGoalsAgainst() {
|
||||||
|
return goalsAgainst;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setGoalsAgainst(int goalsAgainst) {
|
||||||
|
this.goalsAgainst = goalsAgainst;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getGoalDifference() {
|
||||||
|
return goalDifference;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setGoalDifference(int goalDifference) {
|
||||||
|
this.goalDifference = goalDifference;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
package com.example.vdcscore.ui.livegames;
|
||||||
|
|
||||||
|
public class Game {
|
||||||
|
private String id;
|
||||||
|
private String homeTeam;
|
||||||
|
private String awayTeam;
|
||||||
|
private int homeScore;
|
||||||
|
private int awayScore;
|
||||||
|
private String time;
|
||||||
|
private int homePossession;
|
||||||
|
private int awayPossession;
|
||||||
|
private int homeShots;
|
||||||
|
private int awayShots;
|
||||||
|
|
||||||
|
public Game(String id, String homeTeam, String awayTeam, int homeScore, int awayScore, String time) {
|
||||||
|
this.id = id;
|
||||||
|
this.homeTeam = homeTeam;
|
||||||
|
this.awayTeam = awayTeam;
|
||||||
|
this.homeScore = homeScore;
|
||||||
|
this.awayScore = awayScore;
|
||||||
|
this.time = time;
|
||||||
|
// Default mocked stats
|
||||||
|
this.homePossession = 50;
|
||||||
|
this.awayPossession = 50;
|
||||||
|
this.homeShots = 5;
|
||||||
|
this.awayShots = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getHomeTeam() {
|
||||||
|
return homeTeam;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAwayTeam() {
|
||||||
|
return awayTeam;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getHomeScore() {
|
||||||
|
return homeScore;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getAwayScore() {
|
||||||
|
return awayScore;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTime() {
|
||||||
|
return time;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getHomePossession() {
|
||||||
|
return homePossession;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getAwayPossession() {
|
||||||
|
return awayPossession;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getHomeShots() {
|
||||||
|
return homeShots;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getAwayShots() {
|
||||||
|
return awayShots;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,71 @@
|
|||||||
|
package com.example.vdcscore.ui.livegames;
|
||||||
|
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
|
import com.example.vdcscore.R;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class GameAdapter extends RecyclerView.Adapter<GameAdapter.GameViewHolder> {
|
||||||
|
|
||||||
|
private final List<Game> mGames;
|
||||||
|
private final OnGameClickListener mListener;
|
||||||
|
|
||||||
|
public interface OnGameClickListener {
|
||||||
|
void onGameClick(Game game);
|
||||||
|
}
|
||||||
|
|
||||||
|
public GameAdapter(List<Game> games, OnGameClickListener listener) {
|
||||||
|
mGames = games;
|
||||||
|
mListener = listener;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
@Override
|
||||||
|
public GameViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||||
|
View view = LayoutInflater.from(parent.getContext())
|
||||||
|
.inflate(R.layout.item_live_game, parent, false);
|
||||||
|
return new GameViewHolder(view);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBindViewHolder(@NonNull GameViewHolder holder, int position) {
|
||||||
|
Game game = mGames.get(position);
|
||||||
|
holder.bind(game, mListener);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getItemCount() {
|
||||||
|
return mGames.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
static class GameViewHolder extends RecyclerView.ViewHolder {
|
||||||
|
private final TextView time;
|
||||||
|
private final TextView homeTeam;
|
||||||
|
private final TextView awayTeam;
|
||||||
|
private final TextView score;
|
||||||
|
|
||||||
|
public GameViewHolder(@NonNull View itemView) {
|
||||||
|
super(itemView);
|
||||||
|
time = itemView.findViewById(R.id.text_game_time);
|
||||||
|
homeTeam = itemView.findViewById(R.id.text_home_team);
|
||||||
|
awayTeam = itemView.findViewById(R.id.text_away_team);
|
||||||
|
score = itemView.findViewById(R.id.text_score);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void bind(final Game game, final OnGameClickListener listener) {
|
||||||
|
time.setText(game.getTime());
|
||||||
|
homeTeam.setText(game.getHomeTeam());
|
||||||
|
awayTeam.setText(game.getAwayTeam());
|
||||||
|
score.setText(game.getHomeScore() + " - " + game.getAwayScore());
|
||||||
|
|
||||||
|
itemView.setOnClickListener(v -> listener.onGameClick(game));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
package com.example.vdcscore.ui.livegames;
|
||||||
|
|
||||||
|
import androidx.lifecycle.LiveData;
|
||||||
|
import androidx.lifecycle.MutableLiveData;
|
||||||
|
import androidx.lifecycle.ViewModel;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class GameViewModel extends ViewModel {
|
||||||
|
|
||||||
|
private final MutableLiveData<List<Game>> mGames;
|
||||||
|
private final MutableLiveData<Game> mSelectedGame;
|
||||||
|
|
||||||
|
public GameViewModel() {
|
||||||
|
mGames = new MutableLiveData<>();
|
||||||
|
mSelectedGame = new MutableLiveData<>();
|
||||||
|
loadMockGames();
|
||||||
|
}
|
||||||
|
|
||||||
|
public LiveData<List<Game>> getGames() {
|
||||||
|
return mGames;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LiveData<Game> getSelectedGame() {
|
||||||
|
return mSelectedGame;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void selectGame(Game game) {
|
||||||
|
mSelectedGame.setValue(game);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loadMockGames() {
|
||||||
|
List<Game> games = new ArrayList<>();
|
||||||
|
games.add(new Game("1", "VDC", "Benfica", 2, 1, "45'"));
|
||||||
|
games.add(new Game("2", "Sporting", "Porto", 0, 0, "12'"));
|
||||||
|
games.add(new Game("3", "Braga", "V. Guimarães", 1, 3, "88'"));
|
||||||
|
mGames.setValue(games);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
package com.example.vdcscore.ui.livegames;
|
||||||
|
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.TextView;
|
||||||
|
import android.widget.ProgressBar;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.fragment.app.Fragment;
|
||||||
|
import androidx.lifecycle.ViewModelProvider;
|
||||||
|
|
||||||
|
import com.example.vdcscore.R;
|
||||||
|
import com.example.vdcscore.databinding.FragmentLiveGameDetailBinding;
|
||||||
|
|
||||||
|
public class LiveGameDetailFragment extends Fragment {
|
||||||
|
|
||||||
|
private FragmentLiveGameDetailBinding binding;
|
||||||
|
private GameViewModel gameViewModel;
|
||||||
|
|
||||||
|
public View onCreateView(@NonNull LayoutInflater inflater,
|
||||||
|
ViewGroup container, Bundle savedInstanceState) {
|
||||||
|
gameViewModel = new ViewModelProvider(requireActivity()).get(GameViewModel.class);
|
||||||
|
|
||||||
|
binding = FragmentLiveGameDetailBinding.inflate(inflater, container, false);
|
||||||
|
View root = binding.getRoot();
|
||||||
|
|
||||||
|
gameViewModel.getSelectedGame().observe(getViewLifecycleOwner(), game -> {
|
||||||
|
if (game != null) {
|
||||||
|
binding.detailGameTime.setText(game.getTime());
|
||||||
|
binding.detailHomeTeam.setText(game.getHomeTeam());
|
||||||
|
binding.detailAwayTeam.setText(game.getAwayTeam());
|
||||||
|
binding.detailScore.setText(game.getHomeScore() + " - " + game.getAwayScore());
|
||||||
|
|
||||||
|
binding.progressPossession.setProgress(game.getHomePossession());
|
||||||
|
binding.textPossessionHome.setText(game.getHomePossession() + "%");
|
||||||
|
binding.textPossessionAway.setText(game.getAwayPossession() + "%");
|
||||||
|
|
||||||
|
binding.textShotsHome.setText(String.valueOf(game.getHomeShots()));
|
||||||
|
binding.textShotsAway.setText(String.valueOf(game.getAwayShots()));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return root;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDestroyView() {
|
||||||
|
super.onDestroyView();
|
||||||
|
binding = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
package com.example.vdcscore.ui.livegames;
|
||||||
|
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.fragment.app.Fragment;
|
||||||
|
import androidx.lifecycle.ViewModelProvider;
|
||||||
|
import androidx.navigation.Navigation;
|
||||||
|
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||||
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
|
import com.example.vdcscore.R;
|
||||||
|
import com.example.vdcscore.databinding.FragmentLiveGamesBinding;
|
||||||
|
|
||||||
|
public class LiveGamesFragment extends Fragment {
|
||||||
|
|
||||||
|
private FragmentLiveGamesBinding binding;
|
||||||
|
private GameViewModel gameViewModel;
|
||||||
|
|
||||||
|
public View onCreateView(@NonNull LayoutInflater inflater,
|
||||||
|
ViewGroup container, Bundle savedInstanceState) {
|
||||||
|
gameViewModel = new ViewModelProvider(requireActivity()).get(GameViewModel.class);
|
||||||
|
|
||||||
|
binding = FragmentLiveGamesBinding.inflate(inflater, container, false);
|
||||||
|
View root = binding.getRoot();
|
||||||
|
|
||||||
|
RecyclerView recyclerView = binding.recyclerLiveGames;
|
||||||
|
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
|
||||||
|
|
||||||
|
gameViewModel.getGames().observe(getViewLifecycleOwner(), games -> {
|
||||||
|
GameAdapter adapter = new GameAdapter(games, game -> {
|
||||||
|
gameViewModel.selectGame(game);
|
||||||
|
Navigation.findNavController(root).navigate(R.id.action_nav_live_games_to_nav_live_game_detail);
|
||||||
|
});
|
||||||
|
recyclerView.setAdapter(adapter);
|
||||||
|
});
|
||||||
|
|
||||||
|
return root;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDestroyView() {
|
||||||
|
super.onDestroyView();
|
||||||
|
binding = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
7
app/src/main/res/drawable/bg_bottom_sheet_curve.xml
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<solid android:color="#FFFFFF" />
|
||||||
|
<corners
|
||||||
|
android:topLeftRadius="30dp"
|
||||||
|
android:topRightRadius="30dp" />
|
||||||
|
</shape>
|
||||||
10
app/src/main/res/drawable/bg_gradient.xml
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<gradient
|
||||||
|
android:angle="135"
|
||||||
|
android:startColor="#667eea"
|
||||||
|
android:centerColor="#764ba2"
|
||||||
|
android:endColor="#f093fb"
|
||||||
|
android:type="linear" />
|
||||||
|
</shape>
|
||||||
|
|
||||||
9
app/src/main/res/drawable/bg_input_field.xml
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:shape="rectangle">
|
||||||
|
<solid android:color="#F5F5F5" />
|
||||||
|
<corners android:radius="12dp" />
|
||||||
|
<stroke
|
||||||
|
android:width="0dp"
|
||||||
|
android:color="#E0E0E0" />
|
||||||
|
</shape>
|
||||||
11
app/src/main/res/drawable/button_modern.xml
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:shape="rectangle">
|
||||||
|
<gradient
|
||||||
|
android:angle="135"
|
||||||
|
android:startColor="#667eea"
|
||||||
|
android:endColor="#764ba2"
|
||||||
|
android:type="linear" />
|
||||||
|
<corners android:radius="12dp" />
|
||||||
|
</shape>
|
||||||
|
|
||||||
5
app/src/main/res/drawable/circle_decoration.xml
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:shape="oval">
|
||||||
|
<solid android:color="#FFFFFF" />
|
||||||
|
</shape>
|
||||||
8
app/src/main/res/drawable/circle_edit_background.xml
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:shape="oval">
|
||||||
|
<solid android:color="#616161" />
|
||||||
|
<size
|
||||||
|
android:width="36dp"
|
||||||
|
android:height="36dp" />
|
||||||
|
</shape>
|
||||||
17
app/src/main/res/drawable/custom_progress_bg.xml
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<item android:id="@android:id/background">
|
||||||
|
<shape>
|
||||||
|
<corners android:radius="6dp" />
|
||||||
|
<solid android:color="#E0E0E0" />
|
||||||
|
</shape>
|
||||||
|
</item>
|
||||||
|
<item android:id="@android:id/progress">
|
||||||
|
<clip>
|
||||||
|
<shape>
|
||||||
|
<corners android:radius="6dp" />
|
||||||
|
<solid android:color="@color/secondary_color" />
|
||||||
|
</shape>
|
||||||
|
</clip>
|
||||||
|
</item>
|
||||||
|
</layer-list>
|
||||||
15
app/src/main/res/drawable/edit_text_focused.xml
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:shape="rectangle">
|
||||||
|
<solid android:color="#FFFFFF" />
|
||||||
|
<corners android:radius="12dp" />
|
||||||
|
<stroke
|
||||||
|
android:width="2dp"
|
||||||
|
android:color="#667eea" />
|
||||||
|
<padding
|
||||||
|
android:left="16dp"
|
||||||
|
android:top="16dp"
|
||||||
|
android:right="16dp"
|
||||||
|
android:bottom="16dp" />
|
||||||
|
</shape>
|
||||||
|
|
||||||
15
app/src/main/res/drawable/edit_text_modern.xml
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:shape="rectangle">
|
||||||
|
<solid android:color="#FFFFFF" />
|
||||||
|
<corners android:radius="12dp" />
|
||||||
|
<stroke
|
||||||
|
android:width="1dp"
|
||||||
|
android:color="#E0E0E0" />
|
||||||
|
<padding
|
||||||
|
android:left="16dp"
|
||||||
|
android:top="16dp"
|
||||||
|
android:right="16dp"
|
||||||
|
android:bottom="16dp" />
|
||||||
|
</shape>
|
||||||
|
|
||||||
5
app/src/main/res/drawable/header_background.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/primary_color"/>
|
||||||
|
<corners android:radius="8dp"/>
|
||||||
|
</shape>
|
||||||
11
app/src/main/res/drawable/ic_arrow_back.xml
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24">
|
||||||
|
<path
|
||||||
|
android:fillColor="#FF000000"
|
||||||
|
android:pathData="M20,11H7.83l5.59,-5.59L12,4l-8,8 8,8 1.41,-1.41L7.83,13H20v-2z"/>
|
||||||
|
</vector>
|
||||||
|
|
||||||
10
app/src/main/res/drawable/ic_calendar.xml
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24"
|
||||||
|
android:tint="?attr/colorControlNormal">
|
||||||
|
<path
|
||||||
|
android:fillColor="@android:color/white"
|
||||||
|
android:pathData="M19,4h-1V2h-2v2H8V2H6v2H5c-1.11,0 -1.99,0.9 -1.99,2L3,20c0,1.1 0.89,2 2,2h14c1.1,0 2,-0.9 2,-2V6c0,-1.1 -0.9,-2 -2,-2zM19,20H5V10h14v10zM19,8H5V6h14v2z"/>
|
||||||
|
</vector>
|
||||||
11
app/src/main/res/drawable/ic_header_login_bg.xml
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="412dp"
|
||||||
|
android:height="300dp"
|
||||||
|
android:viewportWidth="412"
|
||||||
|
android:viewportHeight="300">
|
||||||
|
|
||||||
|
<path
|
||||||
|
android:fillColor="#121212"
|
||||||
|
android:pathData="M0,0 L412,0 L412,220 C412,220 300,300 0,220 L0,0 Z" />
|
||||||
|
</vector>
|
||||||
11
app/src/main/res/drawable/ic_header_signup_bg.xml
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="412dp"
|
||||||
|
android:height="200dp"
|
||||||
|
android:viewportWidth="412"
|
||||||
|
android:viewportHeight="200">
|
||||||
|
|
||||||
|
<path
|
||||||
|
android:fillColor="#121212"
|
||||||
|
android:pathData="M0,0 L412,0 L412,150 C300,200 100,200 0,150 L0,0 Z" />
|
||||||
|
</vector>
|
||||||
BIN
app/src/main/res/drawable/ic_launcher_foreground.png
Normal file
|
After Width: | Height: | Size: 191 KiB |
@@ -1,30 +0,0 @@
|
|||||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:aapt="http://schemas.android.com/aapt"
|
|
||||||
android:width="108dp"
|
|
||||||
android:height="108dp"
|
|
||||||
android:viewportWidth="108"
|
|
||||||
android:viewportHeight="108">
|
|
||||||
<path android:pathData="M31,63.928c0,0 6.4,-11 12.1,-13.1c7.2,-2.6 26,-1.4 26,-1.4l38.1,38.1L107,108.928l-32,-1L31,63.928z">
|
|
||||||
<aapt:attr name="android:fillColor">
|
|
||||||
<gradient
|
|
||||||
android:endX="85.84757"
|
|
||||||
android:endY="92.4963"
|
|
||||||
android:startX="42.9492"
|
|
||||||
android:startY="49.59793"
|
|
||||||
android:type="linear">
|
|
||||||
<item
|
|
||||||
android:color="#44000000"
|
|
||||||
android:offset="0.0" />
|
|
||||||
<item
|
|
||||||
android:color="#00000000"
|
|
||||||
android:offset="1.0" />
|
|
||||||
</gradient>
|
|
||||||
</aapt:attr>
|
|
||||||
</path>
|
|
||||||
<path
|
|
||||||
android:fillColor="#FFFFFF"
|
|
||||||
android:fillType="nonZero"
|
|
||||||
android:pathData="M65.3,45.828l3.8,-6.6c0.2,-0.4 0.1,-0.9 -0.3,-1.1c-0.4,-0.2 -0.9,-0.1 -1.1,0.3l-3.9,6.7c-6.3,-2.8 -13.4,-2.8 -19.7,0l-3.9,-6.7c-0.2,-0.4 -0.7,-0.5 -1.1,-0.3C38.8,38.328 38.7,38.828 38.9,39.228l3.8,6.6C36.2,49.428 31.7,56.028 31,63.928h46C76.3,56.028 71.8,49.428 65.3,45.828zM43.4,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2c-0.3,-0.7 -0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C45.3,56.528 44.5,57.328 43.4,57.328L43.4,57.328zM64.6,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2s-0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C66.5,56.528 65.6,57.328 64.6,57.328L64.6,57.328z"
|
|
||||||
android:strokeWidth="1"
|
|
||||||
android:strokeColor="#00000000" />
|
|
||||||
</vector>
|
|
||||||
10
app/src/main/res/drawable/ic_location.xml
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24"
|
||||||
|
android:tint="?attr/colorControlNormal">
|
||||||
|
<path
|
||||||
|
android:fillColor="@android:color/white"
|
||||||
|
android:pathData="M12,2C8.13,2 5,5.13 5,9c0,5.25 7,13 7,13s7,-7.75 7,-13c0,-3.87 -3.13,-7 -7,-7zM12,11.5c-1.38,0 -2.5,-1.12 -2.5,-2.5s1.12,-2.5 2.5,-2.5 2.5,1.12 2.5,2.5 -1.12,2.5 -2.5,2.5z"/>
|
||||||
|
</vector>
|
||||||
10
app/src/main/res/drawable/ic_person.xml
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24"
|
||||||
|
android:tint="?attr/colorControlNormal">
|
||||||
|
<path
|
||||||
|
android:fillColor="@android:color/white"
|
||||||
|
android:pathData="M12,12c2.21,0 4,-1.79 4,-4s-1.79,-4 -4,-4 -4,1.79 -4,4 1.79,4 4,4zM12,14c-2.67,0 -8,1.34 -8,4v2h16v-2c0,-2.66 -5.33,-4 -8,-4z"/>
|
||||||
|
</vector>
|
||||||
10
app/src/main/res/drawable/ic_soccer.xml
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24"
|
||||||
|
android:tint="?attr/colorControlNormal">
|
||||||
|
<path
|
||||||
|
android:fillColor="@android:color/white"
|
||||||
|
android:pathData="M11.99,2C6.47,2 2,6.48 2,12s4.47,10 9.99,10C17.52,22 22,17.52 22,12S17.52,2 11.99,2zM18.92,8h-2.95c-0.32,-0.96 -0.78,-1.85 -1.35,-2.68 1.69,0.25 3.19,1.21 4.3,2.68zM14.53,7.69c-0.23,-0.69 -0.52,-1.36 -0.86,-1.99 -0.87,-0.3 -1.8,-0.48 -2.77,-0.48 -0.41,0 -0.81,0.04 -1.2,0.1 0.72,0.92 1.25,2.02 1.51,3.22h3.32zM8.33,5.32c-0.58,0.83 -1.04,1.72 -1.35,2.68H4.08c1.11,-1.47 2.61,-2.43 4.25,-2.68zM4.26,16h3.1c0.41,1.12 1.05,2.15 1.87,3.01 -1.97,-0.47 -3.67,-1.55 -4.97,-3.01zM4,12c0,-1.39 0.42,-2.68 1.13,-3.76 0.18,0.07 0.36,0.13 0.53,0.21 0.42,1.38 1.1,2.63 2,3.7 -0.85,1.02 -1.5,2.2 -1.92,3.5 0,0 -0.01,0 -0.01,0 -1.05,-1.03 -1.73,-2.45 -1.73,-4.06zM11.9,16.5c-1.3,0 -2.48,-0.62 -3.26,-1.59 0.73,-0.89 1.27,-1.93 1.57,-3.06h3.76l0,0c0.3,1.13 0.85,2.17 1.56,3.06 -0.78,0.97 -1.96,1.59 -3.26,1.59zM14.77,19.01c0.82,-0.86 1.46,-1.89 1.88,-3.01h3.1c-1.3,1.46 -3.01,2.54 -4.98,3.01zM17.16,11.94c0.42,-1.29 1.07,-2.48 1.92,-3.5 1.04,1.06 1.72,2.49 1.72,4.06 0,0.15 -0.01,0.29 -0.02,0.44 -1.13,-1.47 -2.62,-2.55 -4.26,-2.81 -0.19,0.64 -0.46,1.25 -0.78,1.82 0.5,0.38 0.98,0.81 1.42,1.29v-1.3z"/>
|
||||||
|
</vector>
|
||||||
5
app/src/main/res/drawable/shape_circle_live.xml
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:shape="oval">
|
||||||
|
<solid android:color="@color/live_indicator" />
|
||||||
|
</shape>
|
||||||
6
app/src/main/res/drawable/shape_score_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="@color/primary_light" />
|
||||||
|
<corners android:radius="8dp" />
|
||||||
|
</shape>
|
||||||
@@ -1,10 +1,301 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:id="@+id/main"
|
android:id="@+id/main"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
|
android:background="@color/background_light"
|
||||||
tools:context=".ui.definicoes.ContaActivity">
|
tools:context=".ui.definicoes.ContaActivity">
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
<com.google.android.material.appbar.AppBarLayout
|
||||||
|
android:id="@+id/appBarLayout"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
|
||||||
|
app:elevation="0dp">
|
||||||
|
|
||||||
|
<com.google.android.material.appbar.MaterialToolbar
|
||||||
|
android:id="@+id/toolbar"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="?attr/actionBarSize"
|
||||||
|
android:background="@color/primary_color"
|
||||||
|
app:title="Definições de Conta"
|
||||||
|
app:titleTextColor="@color/white"
|
||||||
|
app:navigationIcon="@drawable/ic_arrow_back"
|
||||||
|
app:navigationIconTint="@color/white" />
|
||||||
|
|
||||||
|
</com.google.android.material.appbar.AppBarLayout>
|
||||||
|
|
||||||
|
<androidx.core.widget.NestedScrollView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
app:layout_behavior="@string/appbar_scrolling_view_behavior"
|
||||||
|
android:fillViewport="true">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:padding="24dp">
|
||||||
|
|
||||||
|
<!-- Profile Photo Section -->
|
||||||
|
<com.google.android.material.card.MaterialCardView
|
||||||
|
android:id="@+id/cardProfilePhoto"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginBottom="20dp"
|
||||||
|
app:cardCornerRadius="16dp"
|
||||||
|
app:cardElevation="2dp"
|
||||||
|
app:cardBackgroundColor="@color/surface_card"
|
||||||
|
app:strokeWidth="0dp">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:padding="24dp"
|
||||||
|
android:gravity="center">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="Foto de Perfil"
|
||||||
|
android:textSize="18sp"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:textColor="@color/primary_color"
|
||||||
|
android:layout_marginBottom="24dp" />
|
||||||
|
|
||||||
|
<!-- Profile Image -->
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
|
<com.google.android.material.card.MaterialCardView
|
||||||
|
android:id="@+id/cardImageContainer"
|
||||||
|
android:layout_width="120dp"
|
||||||
|
android:layout_height="120dp"
|
||||||
|
app:cardCornerRadius="60dp"
|
||||||
|
app:cardElevation="6dp"
|
||||||
|
app:cardBackgroundColor="#FFFFFF"
|
||||||
|
android:clickable="true"
|
||||||
|
android:focusable="true"
|
||||||
|
android:foreground="?attr/selectableItemBackgroundBorderless">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/imageProfile"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:scaleType="centerCrop"
|
||||||
|
android:contentDescription="Foto de perfil"
|
||||||
|
android:src="@android:drawable/ic_menu_camera"
|
||||||
|
android:background="#E0E0E0" />
|
||||||
|
|
||||||
|
</com.google.android.material.card.MaterialCardView>
|
||||||
|
|
||||||
|
<com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||||
|
android:id="@+id/fabEditPhoto"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
app:fabSize="mini"
|
||||||
|
app:backgroundTint="@color/secondary_color"
|
||||||
|
app:tint="@color/white"
|
||||||
|
android:src="@android:drawable/ic_menu_edit"
|
||||||
|
app:layout_constraintBottom_toBottomOf="@+id/cardImageContainer"
|
||||||
|
app:layout_constraintEnd_toEndOf="@+id/cardImageContainer"/>
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/btnChangePhoto"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="16dp"
|
||||||
|
android:text="Toque para alterar"
|
||||||
|
android:textColor="@color/text_secondary"
|
||||||
|
android:textSize="14sp"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:clickable="true"
|
||||||
|
android:focusable="true"
|
||||||
|
android:padding="8dp"
|
||||||
|
android:background="?attr/selectableItemBackgroundBorderless" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</com.google.android.material.card.MaterialCardView>
|
||||||
|
|
||||||
|
<!-- Name Section -->
|
||||||
|
<com.google.android.material.card.MaterialCardView
|
||||||
|
android:id="@+id/cardName"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginBottom="20dp"
|
||||||
|
app:cardCornerRadius="16dp"
|
||||||
|
app:cardElevation="2dp"
|
||||||
|
app:cardBackgroundColor="@color/surface_card"
|
||||||
|
app:strokeWidth="0dp">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:padding="24dp">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="Nome de Utilizador"
|
||||||
|
android:textSize="18sp"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:textColor="@color/primary_color"
|
||||||
|
android:layout_marginBottom="16dp" />
|
||||||
|
|
||||||
|
<!-- Name Input -->
|
||||||
|
<com.google.android.material.textfield.TextInputLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:hint="Nome completo"
|
||||||
|
app:boxCornerRadiusTopStart="12dp"
|
||||||
|
app:boxCornerRadiusTopEnd="12dp"
|
||||||
|
app:boxCornerRadiusBottomStart="12dp"
|
||||||
|
app:boxCornerRadiusBottomEnd="12dp"
|
||||||
|
app:boxStrokeWidth="1dp"
|
||||||
|
app:boxStrokeColor="@color/divider"
|
||||||
|
app:startIconDrawable="@android:drawable/ic_menu_myplaces"
|
||||||
|
app:startIconTint="@color/text_secondary"
|
||||||
|
app:boxBackgroundMode="outline"
|
||||||
|
style="@style/Widget.Material3.TextInputLayout.OutlinedBox">
|
||||||
|
|
||||||
|
<com.google.android.material.textfield.TextInputEditText
|
||||||
|
android:id="@+id/editName"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:inputType="textPersonName"
|
||||||
|
android:textColor="@color/text_primary"
|
||||||
|
android:textColorHint="@color/text_secondary"
|
||||||
|
android:textSize="16sp"
|
||||||
|
android:padding="16dp"
|
||||||
|
android:background="@android:color/transparent" />
|
||||||
|
|
||||||
|
</com.google.android.material.textfield.TextInputLayout>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/btnSaveAll"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="16dp"
|
||||||
|
android:backgroundTint="@color/primary_color"
|
||||||
|
android:text="Guardar Alterações"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
android:textSize="16sp"
|
||||||
|
android:textStyle="bold" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</com.google.android.material.card.MaterialCardView>
|
||||||
|
|
||||||
|
<!-- Security Section -->
|
||||||
|
<com.google.android.material.card.MaterialCardView
|
||||||
|
android:id="@+id/cardSecurity"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginBottom="24dp"
|
||||||
|
app:cardCornerRadius="16dp"
|
||||||
|
app:cardElevation="2dp"
|
||||||
|
app:cardBackgroundColor="@color/surface_card"
|
||||||
|
app:strokeWidth="0dp">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:padding="24dp">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="Segurança"
|
||||||
|
android:textSize="18sp"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:textColor="@color/primary_color"
|
||||||
|
android:layout_marginBottom="16dp" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="Email"
|
||||||
|
android:textSize="14sp"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:textColor="@color/text_secondary"
|
||||||
|
android:layout_marginBottom="8dp" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/textEmail"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="email@exemplo.com"
|
||||||
|
android:textSize="16sp"
|
||||||
|
android:textColor="@color/text_primary"
|
||||||
|
android:padding="12dp"
|
||||||
|
android:background="@drawable/shape_score_bg"
|
||||||
|
android:backgroundTint="@color/background_light"
|
||||||
|
android:layout_marginBottom="12dp" />
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/btnChangeEmail"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:backgroundTint="@color/text_secondary"
|
||||||
|
android:text="Alterar Email"
|
||||||
|
android:textColor="@color/white" />
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/btnChangePassword"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
android:backgroundTint="@color/text_secondary"
|
||||||
|
android:text="Alterar Password"
|
||||||
|
android:textColor="@color/white" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</com.google.android.material.card.MaterialCardView>
|
||||||
|
|
||||||
|
<!-- Logout Section -->
|
||||||
|
<com.google.android.material.card.MaterialCardView
|
||||||
|
android:id="@+id/cardLogout"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
app:cardCornerRadius="16dp"
|
||||||
|
app:cardElevation="2dp"
|
||||||
|
app:cardBackgroundColor="@color/surface_card"
|
||||||
|
app:strokeWidth="0dp">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:padding="24dp">
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/btnLogout"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:backgroundTint="@color/live_time"
|
||||||
|
android:text="Terminar Sessão"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
android:textSize="16sp"
|
||||||
|
android:textStyle="bold" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</com.google.android.material.card.MaterialCardView>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</androidx.core.widget.NestedScrollView>
|
||||||
|
|
||||||
|
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||||
|
|||||||
@@ -3,130 +3,189 @@
|
|||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:id="@+id/main"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:background="#ECEFF1"
|
android:background="#FFFFFF">
|
||||||
android:id="@+id/main">
|
|
||||||
|
|
||||||
<!-- Título Criar Conta -->
|
<!-- Header Background -->
|
||||||
<TextView
|
<ImageView
|
||||||
android:id="@+id/textView"
|
android:id="@+id/headerBg"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="250dp"
|
||||||
android:layout_marginTop="56dp"
|
android:scaleType="fitXY"
|
||||||
android:text="Criar Conta"
|
android:src="@drawable/ic_header_signup_bg"
|
||||||
android:textSize="35sp"
|
|
||||||
android:textStyle="bold"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintHorizontal_bias="0.497"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toTopOf="parent" />
|
|
||||||
|
|
||||||
<!-- Subtítulo VdcScore -->
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/textView4"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginBottom="15dp"
|
|
||||||
android:text="VdcScore"
|
|
||||||
android:textSize="25sp"
|
|
||||||
android:textStyle="bold"
|
|
||||||
app:layout_constraintBottom_toTopOf="@+id/cardRegister"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toBottomOf="@+id/textView" />
|
|
||||||
|
|
||||||
<!-- Card -->
|
|
||||||
<androidx.cardview.widget.CardView
|
|
||||||
android:id="@+id/cardRegister"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_margin="16dp"
|
|
||||||
android:elevation="10dp"
|
|
||||||
android:padding="24dp"
|
|
||||||
app:cardCornerRadius="18dp"
|
|
||||||
app:cardUseCompatPadding="true"
|
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
android:layout_marginTop="80dp">
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent" />
|
||||||
|
|
||||||
|
<!-- Header Title (as per design image, showing "Sign Up" in header) or Body?
|
||||||
|
The image shows "Sign Up" text in the header area. -->
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="Sign Up"
|
||||||
|
android:textColor="#FFFFFF"
|
||||||
|
android:textSize="32sp"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:layout_marginTop="60dp"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent" />
|
||||||
|
|
||||||
|
<!-- Back Button (Optional, not in Java but good for UX) -->
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Sign Up Form Container -->
|
||||||
|
<ScrollView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
android:fillViewport="true"
|
||||||
|
android:layout_marginTop="160dp"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent">
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="vertical">
|
android:orientation="vertical"
|
||||||
|
android:paddingHorizontal="32dp"
|
||||||
|
android:paddingTop="20dp"
|
||||||
|
android:paddingBottom="20dp"
|
||||||
|
android:background="@drawable/bg_bottom_sheet_curve"> <!-- Implicit white background from activity, but layout structure follows scrolling -->
|
||||||
|
|
||||||
<!-- Nome -->
|
<!-- User Name Label -->
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="Nome de Utilizador"
|
||||||
|
android:textColor="#212121"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:layout_marginBottom="8dp"
|
||||||
|
android:layout_marginStart="4dp"/>
|
||||||
|
|
||||||
<!-- Email -->
|
<com.google.android.material.textfield.TextInputEditText
|
||||||
<EditText
|
android:id="@+id/editUserName"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="50dp"
|
||||||
|
android:background="@drawable/bg_input_field"
|
||||||
|
android:paddingHorizontal="16dp"
|
||||||
|
android:inputType="textPersonName"
|
||||||
|
android:hint="Tony"
|
||||||
|
android:textColor="#424242"
|
||||||
|
android:textColorHint="#BDBDBD"
|
||||||
|
android:textSize="14sp"
|
||||||
|
android:layout_marginBottom="24dp" />
|
||||||
|
|
||||||
|
<!-- Email Label -->
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="Email"
|
||||||
|
android:textColor="#212121"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:layout_marginBottom="8dp"
|
||||||
|
android:layout_marginStart="4dp"/>
|
||||||
|
|
||||||
|
<com.google.android.material.textfield.TextInputEditText
|
||||||
android:id="@+id/editEmail"
|
android:id="@+id/editEmail"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="50dp"
|
||||||
android:layout_marginBottom="12dp"
|
android:background="@drawable/bg_input_field"
|
||||||
android:background="@android:drawable/edit_text"
|
android:paddingHorizontal="16dp"
|
||||||
android:drawableLeft="@android:drawable/ic_menu_send"
|
android:inputType="textEmailAddress"
|
||||||
android:hint="Email"
|
android:hint="email@exemplo.com"
|
||||||
android:padding="12dp"
|
android:textColor="#424242"
|
||||||
android:textColor="#263238"
|
android:textColorHint="#BDBDBD"
|
||||||
android:textColorHint="#90A4AE" />
|
android:textSize="14sp"
|
||||||
|
android:layout_marginBottom="24dp" />
|
||||||
|
|
||||||
<!-- Password -->
|
<!-- Password Label -->
|
||||||
<EditText
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="Password"
|
||||||
|
android:textColor="#212121"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:layout_marginBottom="8dp"
|
||||||
|
android:layout_marginStart="4dp"/>
|
||||||
|
|
||||||
|
<com.google.android.material.textfield.TextInputEditText
|
||||||
android:id="@+id/editPassword2"
|
android:id="@+id/editPassword2"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="50dp"
|
||||||
android:layout_marginBottom="12dp"
|
android:background="@drawable/bg_input_field"
|
||||||
android:background="@android:drawable/edit_text"
|
android:paddingHorizontal="16dp"
|
||||||
android:drawableLeft="@android:drawable/ic_lock_lock"
|
|
||||||
android:hint="Password"
|
|
||||||
android:inputType="textPassword"
|
android:inputType="textPassword"
|
||||||
android:padding="12dp"
|
android:hint="********"
|
||||||
android:textColor="#263238"
|
android:textColor="#424242"
|
||||||
android:textColorHint="#90A4AE" />
|
android:textColorHint="#BDBDBD"
|
||||||
|
android:textSize="14sp"
|
||||||
|
android:layout_marginBottom="24dp" />
|
||||||
|
|
||||||
<!-- Confirmar Password -->
|
<!-- Confirm Password Label -->
|
||||||
<EditText
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="Confirmar Password"
|
||||||
|
android:textColor="#212121"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:layout_marginBottom="8dp"
|
||||||
|
android:layout_marginStart="4dp"/>
|
||||||
|
|
||||||
|
<com.google.android.material.textfield.TextInputEditText
|
||||||
android:id="@+id/editConfirmPassword"
|
android:id="@+id/editConfirmPassword"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="50dp"
|
||||||
android:layout_marginBottom="18dp"
|
android:background="@drawable/bg_input_field"
|
||||||
android:background="@android:drawable/edit_text"
|
android:paddingHorizontal="16dp"
|
||||||
android:drawableLeft="@android:drawable/ic_lock_lock"
|
|
||||||
android:hint="Confirmar Password"
|
|
||||||
android:inputType="textPassword"
|
android:inputType="textPassword"
|
||||||
android:padding="12dp"
|
android:hint="********"
|
||||||
android:textColor="#263238"
|
android:textColor="#424242"
|
||||||
android:textColorHint="#90A4AE" />
|
android:textColorHint="#BDBDBD"
|
||||||
|
android:textSize="14sp"
|
||||||
|
android:layout_marginBottom="32dp" />
|
||||||
|
|
||||||
<!-- Botão -->
|
|
||||||
|
<!-- Sign Up Button -->
|
||||||
<Button
|
<Button
|
||||||
android:id="@+id/btnCreateAccount"
|
android:id="@+id/btnCreateAccount"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="55dp"
|
||||||
|
android:text="Sign Up"
|
||||||
|
android:textAllCaps="false"
|
||||||
|
android:textSize="16sp"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:textColor="#FFFFFF"
|
||||||
|
android:backgroundTint="#000000"
|
||||||
|
app:cornerRadius="12dp"
|
||||||
|
android:layout_marginBottom="24dp" />
|
||||||
|
|
||||||
|
<!-- Login Link -->
|
||||||
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="10dp"
|
android:orientation="horizontal"
|
||||||
android:layout_marginBottom="10dp"
|
android:gravity="center">
|
||||||
android:backgroundTint="#1E88E5"
|
|
||||||
android:padding="12dp"
|
|
||||||
android:text="Criar Conta"
|
|
||||||
android:textColor="#FFFFFF" />
|
|
||||||
|
|
||||||
</LinearLayout>
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="Já tem uma conta? "
|
||||||
|
android:textColor="#757575" />
|
||||||
|
|
||||||
</androidx.cardview.widget.CardView>
|
|
||||||
|
|
||||||
<!-- Voltar ao Login -->
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/txtGoLogin"
|
android:id="@+id/txtGoLogin"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="10dp"
|
android:text="Sign In"
|
||||||
android:text="Já tens conta? Entrar"
|
android:textColor="#000000"
|
||||||
android:textColor="#1E88E5"
|
|
||||||
android:textStyle="bold"
|
android:textStyle="bold"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
android:clickable="true"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
android:focusable="true"/>
|
||||||
app:layout_constraintTop_toBottomOf="@+id/cardRegister" />
|
</LinearLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
</ScrollView>
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|||||||
@@ -5,97 +5,177 @@
|
|||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:background="#ECEFF1">
|
android:background="#FFFFFF">
|
||||||
|
|
||||||
<!-- Card -->
|
<!-- Header Background -->
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/headerBg"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="300dp"
|
||||||
|
android:scaleType="fitXY"
|
||||||
|
android:src="@drawable/ic_header_login_bg"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent" />
|
||||||
|
|
||||||
<!-- Texto "Criar conta" -->
|
<!-- Logo -->
|
||||||
<androidx.cardview.widget.CardView
|
<ImageView
|
||||||
android:id="@+id/cardLogin"
|
android:id="@+id/logoImage"
|
||||||
android:layout_width="0dp"
|
android:layout_width="77dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="80dp"
|
||||||
android:layout_margin="16dp"
|
android:layout_marginTop="60dp"
|
||||||
android:elevation="10dp"
|
android:elevation="4dp"
|
||||||
android:padding="24dp"
|
android:src="@mipmap/ic_launcher"
|
||||||
app:cardCornerRadius="18dp"
|
|
||||||
app:cardUseCompatPadding="true"
|
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
android:layout_marginTop="140dp"
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
|
||||||
>
|
<!-- Login Form Container -->
|
||||||
|
<ScrollView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
android:fillViewport="true"
|
||||||
|
android:layout_marginTop="-40dp"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/headerBg"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent">
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="vertical">
|
android:orientation="vertical"
|
||||||
|
android:paddingHorizontal="32dp"
|
||||||
|
android:paddingTop="20dp"
|
||||||
|
android:paddingBottom="20dp">
|
||||||
|
|
||||||
<!-- Email -->
|
<TextView
|
||||||
<EditText
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="Login"
|
||||||
|
android:textSize="32sp"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:textColor="#212121"
|
||||||
|
android:layout_gravity="center_horizontal"
|
||||||
|
android:layout_marginBottom="40dp" />
|
||||||
|
|
||||||
|
<!-- Email Label -->
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="Email"
|
||||||
|
android:textColor="#212121"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:layout_marginBottom="8dp"
|
||||||
|
android:layout_marginStart="4dp"/>
|
||||||
|
|
||||||
|
<!-- Email Input -->
|
||||||
|
<com.google.android.material.textfield.TextInputEditText
|
||||||
android:id="@+id/editEmail"
|
android:id="@+id/editEmail"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="50dp"
|
||||||
android:layout_marginBottom="12dp"
|
android:background="@drawable/bg_input_field"
|
||||||
android:background="@android:drawable/edit_text"
|
android:paddingHorizontal="16dp"
|
||||||
android:drawableLeft="@android:drawable/ic_menu_send"
|
android:inputType="textEmailAddress"
|
||||||
android:hint="Email"
|
android:hint="email@exemplo.com"
|
||||||
android:padding="12dp"
|
android:textColor="#424242"
|
||||||
android:textColor="#263238"
|
android:textColorHint="#BDBDBD"
|
||||||
android:textColorHint="#90A4AE" />
|
android:textSize="14sp"
|
||||||
|
android:layout_marginBottom="24dp" />
|
||||||
|
|
||||||
<!-- Password -->
|
<!-- Password Label -->
|
||||||
<EditText
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="Password"
|
||||||
|
android:textColor="#212121"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:layout_marginBottom="8dp"
|
||||||
|
android:layout_marginStart="4dp"/>
|
||||||
|
|
||||||
|
<!-- Password Input -->
|
||||||
|
<com.google.android.material.textfield.TextInputEditText
|
||||||
android:id="@+id/editPassword2"
|
android:id="@+id/editPassword2"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="50dp"
|
||||||
android:layout_marginBottom="18dp"
|
android:background="@drawable/bg_input_field"
|
||||||
android:background="@android:drawable/edit_text"
|
android:paddingHorizontal="16dp"
|
||||||
android:drawableLeft="@android:drawable/ic_lock_lock"
|
|
||||||
android:hint="Password"
|
|
||||||
android:inputType="textPassword"
|
android:inputType="textPassword"
|
||||||
android:padding="12dp"
|
android:hint="********"
|
||||||
android:textColor="#263238"
|
android:textColor="#424242"
|
||||||
android:textColorHint="#90A4AE" />
|
android:textColorHint="#BDBDBD"
|
||||||
|
android:textSize="14sp"
|
||||||
|
android:layout_marginBottom="16dp" />
|
||||||
|
|
||||||
<!-- Botão -->
|
<!-- Remember Me & Forgot Password -->
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:layout_marginBottom="32dp">
|
||||||
|
|
||||||
|
<CheckBox
|
||||||
|
android:id="@+id/checkRememberMe"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="Lembrar"
|
||||||
|
android:textColor="#757575"/>
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
android:layout_weight="1" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/txtForgotPassword"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="Esqueceu a senha?"
|
||||||
|
android:textColor="#757575"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:textSize="12sp"
|
||||||
|
android:clickable="true"
|
||||||
|
android:focusable="true"/>
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<!-- Login Button -->
|
||||||
<Button
|
<Button
|
||||||
android:id="@+id/btnLogin"
|
android:id="@+id/btnLogin"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="55dp"
|
||||||
|
android:text="Login"
|
||||||
|
android:textAllCaps="false"
|
||||||
|
android:textSize="16sp"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:textColor="#FFFFFF"
|
||||||
|
android:backgroundTint="#000000"
|
||||||
|
app:cornerRadius="12dp"
|
||||||
|
android:layout_marginBottom="24dp" />
|
||||||
|
|
||||||
|
<!-- Sign Up Link -->
|
||||||
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="10dp"
|
android:orientation="horizontal"
|
||||||
android:layout_marginBottom="10dp"
|
android:gravity="center">
|
||||||
android:backgroundTint="#1E88E5"
|
|
||||||
android:padding="12dp"
|
|
||||||
android:text="Entrar"
|
|
||||||
android:textColor="#FFFFFF" />
|
|
||||||
|
|
||||||
</LinearLayout>
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
</androidx.cardview.widget.CardView>
|
android:layout_height="wrap_content"
|
||||||
|
android:text="Não tem uma conta? "
|
||||||
|
android:textColor="#757575" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/txtRegister"
|
android:id="@+id/txtRegister"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="30dp"
|
android:text="Criar Conta"
|
||||||
android:text="Criar conta"
|
android:textColor="#000000"
|
||||||
android:textColor="#1E88E5"
|
|
||||||
android:textStyle="bold"
|
android:textStyle="bold"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
android:clickable="true"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
android:focusable="true"/>
|
||||||
app:layout_constraintTop_toBottomOf="@+id/cardLogin" />
|
</LinearLayout>
|
||||||
|
|
||||||
<TextView
|
</LinearLayout>
|
||||||
android:id="@+id/textView3"
|
</ScrollView>
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginBottom="50dp"
|
|
||||||
android:text="VdcScore"
|
|
||||||
android:textSize="25sp"
|
|
||||||
android:textStyle="bold"
|
|
||||||
app:layout_constraintBottom_toTopOf="@+id/cardLogin"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintStart_toStartOf="parent" />
|
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|||||||
@@ -20,6 +20,9 @@
|
|||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:layout_gravity="start"
|
android:layout_gravity="start"
|
||||||
android:fitsSystemWindows="true"
|
android:fitsSystemWindows="true"
|
||||||
|
android:background="@color/white"
|
||||||
|
app:itemTextColor="@color/black"
|
||||||
|
app:itemIconTint="@color/black"
|
||||||
app:headerLayout="@layout/nav_header_main"
|
app:headerLayout="@layout/nav_header_main"
|
||||||
app:menu="@menu/activity_main_drawer" />
|
app:menu="@menu/activity_main_drawer" />
|
||||||
</androidx.drawerlayout.widget.DrawerLayout>
|
</androidx.drawerlayout.widget.DrawerLayout>
|
||||||
156
app/src/main/res/layout/activity_recuperar_password.xml
Normal file
@@ -0,0 +1,156 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:background="@drawable/bg_gradient">
|
||||||
|
|
||||||
|
<!-- Back Button -->
|
||||||
|
<ImageButton
|
||||||
|
android:id="@+id/btnBack"
|
||||||
|
android:layout_width="48dp"
|
||||||
|
android:layout_height="48dp"
|
||||||
|
android:layout_marginStart="16dp"
|
||||||
|
android:layout_marginTop="16dp"
|
||||||
|
android:background="?attr/selectableItemBackgroundBorderless"
|
||||||
|
android:src="@drawable/ic_arrow_back"
|
||||||
|
android:tint="#FFFFFF"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
<!-- Logo/Title -->
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/textViewTitle"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="60dp"
|
||||||
|
android:text="Recuperar Palavra-passe"
|
||||||
|
android:textSize="28sp"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:textColor="#FFFFFF"
|
||||||
|
android:gravity="center"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
<!-- Subtitle -->
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/textSubtitle"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="32dp"
|
||||||
|
android:layout_marginEnd="32dp"
|
||||||
|
android:layout_marginTop="16dp"
|
||||||
|
android:text="Introduza o seu email e enviaremos instruções para recuperar a sua palavra-passe"
|
||||||
|
android:textSize="14sp"
|
||||||
|
android:textColor="#FFFFFF"
|
||||||
|
android:alpha="0.9"
|
||||||
|
android:gravity="center"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/textViewTitle" />
|
||||||
|
|
||||||
|
<!-- Card -->
|
||||||
|
<androidx.cardview.widget.CardView
|
||||||
|
android:id="@+id/cardRecuperar"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="24dp"
|
||||||
|
android:layout_marginEnd="24dp"
|
||||||
|
android:layout_marginTop="48dp"
|
||||||
|
android:elevation="8dp"
|
||||||
|
android:padding="28dp"
|
||||||
|
app:cardCornerRadius="24dp"
|
||||||
|
app:cardBackgroundColor="#FFFFFF"
|
||||||
|
app:cardUseCompatPadding="true"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/textSubtitle">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<!-- Email -->
|
||||||
|
<com.google.android.material.textfield.TextInputLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginBottom="24dp"
|
||||||
|
android:hint="Email"
|
||||||
|
app:boxCornerRadiusTopStart="12dp"
|
||||||
|
app:boxCornerRadiusTopEnd="12dp"
|
||||||
|
app:boxCornerRadiusBottomStart="12dp"
|
||||||
|
app:boxCornerRadiusBottomEnd="12dp"
|
||||||
|
app:boxStrokeWidth="0dp"
|
||||||
|
app:startIconDrawable="@android:drawable/ic_dialog_email"
|
||||||
|
app:startIconTint="#667eea"
|
||||||
|
style="@style/Widget.Material3.TextInputLayout.OutlinedBox">
|
||||||
|
|
||||||
|
<com.google.android.material.textfield.TextInputEditText
|
||||||
|
android:id="@+id/editEmailRecuperar"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:inputType="textEmailAddress"
|
||||||
|
android:textColor="#263238"
|
||||||
|
android:textColorHint="#90A4AE"
|
||||||
|
android:padding="16dp" />
|
||||||
|
|
||||||
|
</com.google.android.material.textfield.TextInputLayout>
|
||||||
|
|
||||||
|
<!-- Botão -->
|
||||||
|
<Button
|
||||||
|
android:id="@+id/btnRecuperar"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="56dp"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
android:background="@drawable/button_modern"
|
||||||
|
android:text="Enviar Email"
|
||||||
|
android:textColor="#FFFFFF"
|
||||||
|
android:textSize="16sp"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:elevation="4dp"
|
||||||
|
android:stateListAnimator="@null" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</androidx.cardview.widget.CardView>
|
||||||
|
|
||||||
|
<!-- Voltar ao Login -->
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="24dp"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:gravity="center"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/cardRecuperar">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="Lembras-te da palavra-passe? "
|
||||||
|
android:textColor="#FFFFFF"
|
||||||
|
android:textSize="14sp"
|
||||||
|
android:alpha="0.9" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/txtVoltarLogin"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="Entrar"
|
||||||
|
android:textColor="#FFFFFF"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:textSize="14sp"
|
||||||
|
android:clickable="true"
|
||||||
|
android:focusable="true"
|
||||||
|
android:padding="4dp"
|
||||||
|
android:background="?attr/selectableItemBackground" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
||||||
@@ -9,26 +9,21 @@
|
|||||||
<com.google.android.material.appbar.AppBarLayout
|
<com.google.android.material.appbar.AppBarLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:theme="@style/Theme.VdcScore.AppBarOverlay">
|
android:background="@color/white"
|
||||||
|
android:theme="@style/ThemeOverlay.AppCompat.Light"> <!-- Light theme for dark text -->
|
||||||
|
|
||||||
<androidx.appcompat.widget.Toolbar
|
<androidx.appcompat.widget.Toolbar
|
||||||
android:id="@+id/toolbar"
|
android:id="@+id/toolbar"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="?attr/actionBarSize"
|
android:layout_height="?attr/actionBarSize"
|
||||||
android:background="?attr/colorPrimary"
|
android:background="@color/white"
|
||||||
|
app:titleTextColor="@color/black"
|
||||||
app:popupTheme="@style/Theme.VdcScore.PopupOverlay" />
|
app:popupTheme="@style/Theme.VdcScore.PopupOverlay" />
|
||||||
|
|
||||||
</com.google.android.material.appbar.AppBarLayout>
|
</com.google.android.material.appbar.AppBarLayout>
|
||||||
|
|
||||||
<include layout="@layout/content_main" />
|
<include layout="@layout/content_main" />
|
||||||
|
|
||||||
<com.google.android.material.floatingactionbutton.FloatingActionButton
|
|
||||||
android:id="@+id/fab"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_gravity="bottom|end"
|
|
||||||
android:layout_marginEnd="@dimen/fab_margin"
|
|
||||||
android:layout_marginBottom="16dp"
|
|
||||||
app:srcCompat="@android:drawable/ic_dialog_email" />
|
|
||||||
|
|
||||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||||
232
app/src/main/res/layout/fragment_club_detail.xml
Normal file
@@ -0,0 +1,232 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.core.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:fillViewport="true"
|
||||||
|
android:background="@color/white"
|
||||||
|
tools:context=".ui.clubs.ClubDetailFragment">
|
||||||
|
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:padding="24dp">
|
||||||
|
|
||||||
|
<!-- Club Logo (Circular) -->
|
||||||
|
<androidx.cardview.widget.CardView
|
||||||
|
android:id="@+id/cardLogo"
|
||||||
|
android:layout_width="200dp"
|
||||||
|
android:layout_height="200dp"
|
||||||
|
app:cardCornerRadius="100dp"
|
||||||
|
app:cardElevation="8dp"
|
||||||
|
app:cardBackgroundColor="@color/white"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
android:layout_marginTop="16dp">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/image_detail_logo"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:scaleType="centerCrop"
|
||||||
|
android:padding="0dp"
|
||||||
|
tools:src="@mipmap/ic_launcher_round"/>
|
||||||
|
</androidx.cardview.widget.CardView>
|
||||||
|
|
||||||
|
<!-- CLUBE Label -->
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/label_club"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="CLUBE:"
|
||||||
|
android:textSize="14sp"
|
||||||
|
android:textColor="#616161"
|
||||||
|
android:layout_marginTop="32dp"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/cardLogo"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"/>
|
||||||
|
|
||||||
|
<!-- Club Name -->
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/text_detail_club_name"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
tools:text="Inter Freguesias Vila do Conde"
|
||||||
|
android:textSize="28sp"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:textColor="#0D47A1"
|
||||||
|
android:layout_marginTop="4dp"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/label_club"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"/>
|
||||||
|
|
||||||
|
<!-- President Section -->
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/layout_president"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:layout_marginTop="24dp"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/text_detail_club_name"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:layout_width="40dp"
|
||||||
|
android:layout_height="40dp"
|
||||||
|
android:src="@drawable/ic_person"
|
||||||
|
app:tint="#455A64"
|
||||||
|
android:background="@drawable/circle_edit_background"
|
||||||
|
android:backgroundTint="#ECEFF1"
|
||||||
|
android:padding="8dp"/>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:layout_marginStart="16dp">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="PRESIDENTE:"
|
||||||
|
android:textSize="12sp"
|
||||||
|
android:textColor="#616161"/>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/text_detail_president"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
tools:text="João Silva"
|
||||||
|
android:textSize="16sp"
|
||||||
|
android:textColor="#263238"
|
||||||
|
android:textStyle="bold"/>
|
||||||
|
</LinearLayout>
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<!-- Address Section -->
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/layout_address"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:layout_marginTop="16dp"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/layout_president"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:layout_width="40dp"
|
||||||
|
android:layout_height="40dp"
|
||||||
|
android:src="@drawable/ic_location"
|
||||||
|
app:tint="#455A64"
|
||||||
|
android:background="@drawable/circle_edit_background"
|
||||||
|
android:backgroundTint="#ECEFF1"
|
||||||
|
android:padding="8dp"/>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:layout_marginStart="16dp">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="MORADA:"
|
||||||
|
android:textSize="12sp"
|
||||||
|
android:textColor="#616161"/>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/text_detail_address"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
tools:text="Rua Desportiva 123"
|
||||||
|
android:textSize="16sp"
|
||||||
|
android:textColor="#263238"
|
||||||
|
android:textStyle="bold"/>
|
||||||
|
</LinearLayout>
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<!-- Foundation Section -->
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/layout_foundation"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:layout_marginTop="16dp"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/layout_address"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:layout_width="40dp"
|
||||||
|
android:layout_height="40dp"
|
||||||
|
android:src="@drawable/ic_calendar"
|
||||||
|
app:tint="#455A64"
|
||||||
|
android:background="@drawable/circle_edit_background"
|
||||||
|
android:backgroundTint="#ECEFF1"
|
||||||
|
android:padding="8dp"/>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:layout_marginStart="16dp">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="ANO DE FUNDAÇÃO:"
|
||||||
|
android:textSize="12sp"
|
||||||
|
android:textColor="#616161"/>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/text_detail_foundation"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
tools:text="1995"
|
||||||
|
android:textSize="16sp"
|
||||||
|
android:textColor="#263238"
|
||||||
|
android:textStyle="bold"/>
|
||||||
|
</LinearLayout>
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<!-- Stadium Section (Hidden per screenshot but kept in model, or should I show it?)
|
||||||
|
The screenshot doesn't explicitly show Stadium but the code had it.
|
||||||
|
I will hide it for now to match screenshot strictly or add it if plenty space?
|
||||||
|
The user said "appears like this", implies following the screenshot.
|
||||||
|
But previously stadium was shown. I will add it as well for completeness if it fits,
|
||||||
|
or just omit if the screenshot is strict.
|
||||||
|
Screenshot: CLUBE, PRESIDENTE, MORADA, ANO DE FUNDACAO. No Stadium.
|
||||||
|
I will omit Stadium from UI to match unique request "like this".
|
||||||
|
-->
|
||||||
|
|
||||||
|
<!-- Players Button -->
|
||||||
|
<Button
|
||||||
|
android:id="@+id/btn_players"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="60dp"
|
||||||
|
android:text="JOGADORES\n(Ver Lista)"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
android:textSize="16sp"
|
||||||
|
android:textStyle="bold"
|
||||||
|
app:cornerRadius="12dp"
|
||||||
|
android:backgroundTint="#1976D2"
|
||||||
|
app:icon="@drawable/ic_soccer"
|
||||||
|
app:iconGravity="textStart"
|
||||||
|
app:iconSize="32dp"
|
||||||
|
app:iconTint="@color/white"
|
||||||
|
android:gravity="center"
|
||||||
|
android:layout_marginTop="40dp"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/layout_foundation"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintVertical_bias="1.0"
|
||||||
|
android:layout_marginBottom="20dp"/>
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
</androidx.core.widget.NestedScrollView>
|
||||||
41
app/src/main/res/layout/fragment_club_players.xml
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:background="#F5F5F5"
|
||||||
|
tools:context=".ui.clubs.ClubPlayersFragment">
|
||||||
|
|
||||||
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
android:id="@+id/recycler_players_list"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:padding="8dp"
|
||||||
|
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"/>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/text_no_players"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="Sem jogadores inscritos"
|
||||||
|
android:textSize="18sp"
|
||||||
|
android:textColor="#757575"
|
||||||
|
android:visibility="gone"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"/>
|
||||||
|
|
||||||
|
<ProgressBar
|
||||||
|
android:id="@+id/progressBarPlayers"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"/>
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
55
app/src/main/res/layout/fragment_clubs.xml
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout 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="match_parent"
|
||||||
|
android:background="@color/background_light">
|
||||||
|
|
||||||
|
<com.google.android.material.button.MaterialButtonToggleGroup
|
||||||
|
android:id="@+id/toggleGroupEscalao"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="16dp"
|
||||||
|
app:checkedButton="@id/btnSeniores"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
app:singleSelection="true">
|
||||||
|
|
||||||
|
<com.google.android.material.button.MaterialButton
|
||||||
|
android:id="@+id/btnSeniores"
|
||||||
|
style="?attr/materialButtonOutlinedStyle"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="Seniores" />
|
||||||
|
|
||||||
|
<com.google.android.material.button.MaterialButton
|
||||||
|
android:id="@+id/btnJuniores"
|
||||||
|
style="?attr/materialButtonOutlinedStyle"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="Juniores" />
|
||||||
|
|
||||||
|
</com.google.android.material.button.MaterialButtonToggleGroup>
|
||||||
|
|
||||||
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
android:id="@+id/recycler_clubs"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
android:layout_marginTop="16dp"
|
||||||
|
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/toggleGroupEscalao" />
|
||||||
|
|
||||||
|
<ProgressBar
|
||||||
|
android:id="@+id/progress_bar"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
@@ -3,7 +3,7 @@
|
|||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:background="#ECEFF1">
|
android:background="@color/background_light">
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
@@ -16,7 +16,7 @@
|
|||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="Definições"
|
android:text="Definições"
|
||||||
android:textColor="#263238"
|
android:textColor="@color/primary_color"
|
||||||
android:textSize="28sp"
|
android:textSize="28sp"
|
||||||
android:textStyle="bold" />
|
android:textStyle="bold" />
|
||||||
|
|
||||||
@@ -25,7 +25,7 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="4dp"
|
android:layout_marginTop="4dp"
|
||||||
android:text="Personaliza a aplicação de acordo com o teu gosto."
|
android:text="Personaliza a aplicação de acordo com o teu gosto."
|
||||||
android:textColor="#546E7A"
|
android:textColor="@color/text_secondary"
|
||||||
android:textSize="14sp" />
|
android:textSize="14sp" />
|
||||||
|
|
||||||
<com.google.android.material.card.MaterialCardView
|
<com.google.android.material.card.MaterialCardView
|
||||||
@@ -33,30 +33,34 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="20dp"
|
android:layout_marginTop="20dp"
|
||||||
|
android:clickable="true"
|
||||||
|
android:focusable="true"
|
||||||
android:foreground="?attr/selectableItemBackground"
|
android:foreground="?attr/selectableItemBackground"
|
||||||
app:cardCornerRadius="16dp"
|
app:cardCornerRadius="16dp"
|
||||||
app:cardUseCompatPadding="true"
|
app:cardElevation="0dp"
|
||||||
app:strokeColor="#CFD8DC"
|
app:strokeColor="@color/divider"
|
||||||
app:strokeWidth="1dp">
|
app:strokeWidth="1dp"
|
||||||
|
app:cardBackgroundColor="@color/surface_card">
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:gravity="center_vertical"
|
android:gravity="center_vertical"
|
||||||
android:orientation="horizontal"
|
android:orientation="horizontal"
|
||||||
android:padding="18dp">
|
android:padding="20dp">
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:layout_width="40dp"
|
android:layout_width="40dp"
|
||||||
android:layout_height="40dp"
|
android:layout_height="40dp"
|
||||||
android:contentDescription="@string/menu_definicoes"
|
android:contentDescription="@string/menu_definicoes"
|
||||||
android:padding="4dp"
|
android:padding="4dp"
|
||||||
android:src="@android:drawable/ic_menu_manage" />
|
android:src="@android:drawable/ic_menu_manage"
|
||||||
|
app:tint="@color/black"/>
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginStart="12dp"
|
android:layout_marginStart="16dp"
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
|
||||||
@@ -64,7 +68,7 @@
|
|||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="Conta"
|
android:text="Conta"
|
||||||
android:textColor="#263238"
|
android:textColor="@color/black"
|
||||||
android:textSize="18sp"
|
android:textSize="18sp"
|
||||||
android:textStyle="bold" />
|
android:textStyle="bold" />
|
||||||
|
|
||||||
@@ -72,7 +76,7 @@
|
|||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="Atualiza os teus dados pessoais"
|
android:text="Atualiza os teus dados pessoais"
|
||||||
android:textColor="#607D8B"
|
android:textColor="@color/text_secondary"
|
||||||
android:textSize="14sp" />
|
android:textSize="14sp" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
@@ -80,7 +84,8 @@
|
|||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:contentDescription="@string/menu_definicoes"
|
android:contentDescription="@string/menu_definicoes"
|
||||||
android:src="@android:drawable/ic_media_next" />
|
android:src="@android:drawable/ic_media_next"
|
||||||
|
app:tint="@color/text_secondary"/>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
</com.google.android.material.card.MaterialCardView>
|
</com.google.android.material.card.MaterialCardView>
|
||||||
|
|
||||||
@@ -89,13 +94,16 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="16dp"
|
android:layout_marginTop="16dp"
|
||||||
app:cardCornerRadius="16dp"
|
app:cardCornerRadius="16dp"
|
||||||
app:cardUseCompatPadding="true">
|
app:cardElevation="0dp"
|
||||||
|
app:strokeColor="@color/divider"
|
||||||
|
app:strokeWidth="1dp"
|
||||||
|
app:cardBackgroundColor="@color/surface_card">
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
android:padding="18dp">
|
android:padding="20dp">
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
@@ -113,7 +121,7 @@
|
|||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="Notificações"
|
android:text="Notificações"
|
||||||
android:textColor="#263238"
|
android:textColor="@color/black"
|
||||||
android:textSize="16sp"
|
android:textSize="16sp"
|
||||||
android:textStyle="bold" />
|
android:textStyle="bold" />
|
||||||
|
|
||||||
@@ -122,7 +130,7 @@
|
|||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="Ativadas"
|
android:text="Ativadas"
|
||||||
android:textColor="#607D8B"
|
android:textColor="@color/text_secondary"
|
||||||
android:textSize="14sp" />
|
android:textSize="14sp" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
@@ -136,8 +144,8 @@
|
|||||||
<View
|
<View
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="1dp"
|
android:layout_height="1dp"
|
||||||
android:layout_marginVertical="12dp"
|
android:layout_marginVertical="16dp"
|
||||||
android:background="#ECEFF1" />
|
android:background="@color/divider" />
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
@@ -155,7 +163,7 @@
|
|||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="Modo escuro"
|
android:text="Modo escuro"
|
||||||
android:textColor="#263238"
|
android:textColor="@color/black"
|
||||||
android:textSize="16sp"
|
android:textSize="16sp"
|
||||||
android:textStyle="bold" />
|
android:textStyle="bold" />
|
||||||
|
|
||||||
@@ -164,7 +172,7 @@
|
|||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="Inativo"
|
android:text="Inativo"
|
||||||
android:textColor="#607D8B"
|
android:textColor="@color/text_secondary"
|
||||||
android:textSize="14sp" />
|
android:textSize="14sp" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
@@ -181,19 +189,22 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="16dp"
|
android:layout_marginTop="16dp"
|
||||||
app:cardCornerRadius="16dp"
|
app:cardCornerRadius="16dp"
|
||||||
app:cardUseCompatPadding="true">
|
app:cardElevation="0dp"
|
||||||
|
app:strokeColor="@color/divider"
|
||||||
|
app:strokeWidth="1dp"
|
||||||
|
app:cardBackgroundColor="@color/surface_card">
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
android:padding="18dp">
|
android:padding="20dp">
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="Ajuda e suporte"
|
android:text="Ajuda e suporte"
|
||||||
android:textColor="#263238"
|
android:textColor="@color/black"
|
||||||
android:textSize="16sp"
|
android:textSize="16sp"
|
||||||
android:textStyle="bold" />
|
android:textStyle="bold" />
|
||||||
|
|
||||||
@@ -202,20 +213,19 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="4dp"
|
android:layout_marginTop="4dp"
|
||||||
android:text="Consulta a nossa base de conhecimento ou fala connosco."
|
android:text="Consulta a nossa base de conhecimento ou fala connosco."
|
||||||
android:textColor="#607D8B"
|
android:textColor="@color/text_secondary"
|
||||||
android:textSize="14sp" />
|
android:textSize="14sp" />
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
android:id="@+id/btnOpenSystemSettings"
|
android:id="@+id/btnOpenSystemSettings"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="12dp"
|
android:layout_marginTop="16dp"
|
||||||
android:backgroundTint="#1E88E5"
|
android:backgroundTint="@color/black"
|
||||||
android:text="Abrir definições do sistema"
|
android:text="Abrir definições do sistema"
|
||||||
android:textAllCaps="false"
|
android:textAllCaps="false"
|
||||||
android:textColor="#FFFFFF" />
|
android:textColor="@color/white" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
</com.google.android.material.card.MaterialCardView>
|
</com.google.android.material.card.MaterialCardView>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
</ScrollView>
|
</ScrollView>
|
||||||
|
|
||||||
|
|||||||
@@ -1,22 +1,27 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:padding="16dp"
|
||||||
|
android:background="@color/background_light"
|
||||||
tools:context=".ui.gallery.GalleryFragment">
|
tools:context=".ui.gallery.GalleryFragment">
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/text_gallery"
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginStart="8dp"
|
android:text="Jornadas"
|
||||||
android:layout_marginTop="8dp"
|
android:textSize="24sp"
|
||||||
android:layout_marginEnd="8dp"
|
android:textStyle="bold"
|
||||||
android:textAlignment="center"
|
android:textColor="@color/primary_color"
|
||||||
android:textSize="20sp"
|
android:layout_marginBottom="16dp" />
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
android:id="@+id/recycler_matchdays"
|
||||||
app:layout_constraintTop_toTopOf="parent" />
|
android:layout_width="match_parent"
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
android:layout_height="match_parent"
|
||||||
|
android:clipToPadding="false"
|
||||||
|
android:paddingBottom="16dp"/>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
@@ -1,22 +1,80 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:padding="16dp"
|
||||||
|
android:background="@color/background_light"
|
||||||
tools:context=".ui.home.HomeFragment">
|
tools:context=".ui.home.HomeFragment">
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/text_home"
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginStart="8dp"
|
android:text="Classificação"
|
||||||
android:layout_marginTop="8dp"
|
android:textSize="28sp"
|
||||||
android:layout_marginEnd="8dp"
|
android:textStyle="bold"
|
||||||
android:textAlignment="center"
|
android:textColor="@color/primary_color"
|
||||||
android:textSize="20sp"
|
android:layout_marginBottom="24dp" />
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
<!-- Table Header (Clean) -->
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
<LinearLayout
|
||||||
app:layout_constraintTop_toTopOf="parent" />
|
android:layout_width="match_parent"
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:paddingVertical="12dp"
|
||||||
|
android:paddingHorizontal="4dp"
|
||||||
|
android:background="#00000000">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="40dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="#"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:textColor="@color/black"
|
||||||
|
android:textSize="14sp"/>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:text="Clube"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:textColor="@color/black"
|
||||||
|
android:textSize="14sp"/>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="40dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:gravity="center"
|
||||||
|
android:text="J"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:textColor="@color/black"
|
||||||
|
android:textSize="14sp"
|
||||||
|
android:tooltipText="Jogos" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="40dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:gravity="center"
|
||||||
|
android:text="Pts"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:textColor="@color/black"
|
||||||
|
android:textSize="14sp"/>
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="1dp"
|
||||||
|
android:background="@color/divider"
|
||||||
|
android:layout_marginBottom="8dp"/>
|
||||||
|
|
||||||
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
android:id="@+id/recycler_standings"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:clipToPadding="false"
|
||||||
|
android:paddingTop="4dp" />
|
||||||
|
</LinearLayout>
|
||||||
201
app/src/main/res/layout/fragment_live_game_detail.xml
Normal file
@@ -0,0 +1,201 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<ScrollView 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="match_parent"
|
||||||
|
android:background="@color/background_light">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:padding="16dp">
|
||||||
|
|
||||||
|
<!-- Header Card -->
|
||||||
|
<androidx.cardview.widget.CardView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
app:cardBackgroundColor="@color/primary_color"
|
||||||
|
app:cardCornerRadius="24dp"
|
||||||
|
app:cardElevation="6dp">
|
||||||
|
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:padding="24dp">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/detail_game_time"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="65'"
|
||||||
|
android:textColor="@color/live_time"
|
||||||
|
android:textSize="18sp"
|
||||||
|
android:textStyle="bold"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/detail_home_team"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="16dp"
|
||||||
|
android:gravity="center"
|
||||||
|
android:text="Home"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
android:textSize="22sp"
|
||||||
|
android:textStyle="bold"
|
||||||
|
app:layout_constraintEnd_toStartOf="@+id/detail_score"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/detail_game_time" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/detail_score"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginHorizontal="16dp"
|
||||||
|
android:text="1 - 1"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
android:textSize="36sp"
|
||||||
|
android:textStyle="bold"
|
||||||
|
app:layout_constraintBottom_toBottomOf="@+id/detail_home_team"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="@+id/detail_home_team" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/detail_away_team"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:gravity="center"
|
||||||
|
android:text="Away"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
android:textSize="22sp"
|
||||||
|
android:textStyle="bold"
|
||||||
|
app:layout_constraintBottom_toBottomOf="@+id/detail_home_team"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toEndOf="@+id/detail_score"
|
||||||
|
app:layout_constraintTop_toTopOf="@+id/detail_home_team" />
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
</androidx.cardview.widget.CardView>
|
||||||
|
|
||||||
|
<!-- Stats Section -->
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/text_stats_title"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="24dp"
|
||||||
|
android:layout_marginBottom="16dp"
|
||||||
|
android:text="Estatísticas ao Vivo"
|
||||||
|
android:textColor="@color/text_primary"
|
||||||
|
android:textSize="20sp"
|
||||||
|
android:textStyle="bold" />
|
||||||
|
|
||||||
|
<androidx.cardview.widget.CardView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
app:cardCornerRadius="16dp"
|
||||||
|
app:cardElevation="2dp"
|
||||||
|
app:cardBackgroundColor="@color/surface_card">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:padding="20dp">
|
||||||
|
|
||||||
|
<!-- Possession -->
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/label_possession"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:text="Posse de Bola"
|
||||||
|
android:textColor="@color/text_secondary"
|
||||||
|
android:textStyle="bold" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
android:gravity="center_vertical">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/text_possession_home"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="50%"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:textColor="@color/text_primary"
|
||||||
|
android:layout_marginEnd="12dp"/>
|
||||||
|
|
||||||
|
<ProgressBar
|
||||||
|
android:id="@+id/progress_possession"
|
||||||
|
style="?android:attr/progressBarStyleHorizontal"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="12dp"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:max="100"
|
||||||
|
android:progress="50"
|
||||||
|
android:progressDrawable="@drawable/custom_progress_bg"/>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/text_possession_away"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="50%"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:textColor="@color/text_primary"
|
||||||
|
android:layout_marginStart="12dp"/>
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="1dp"
|
||||||
|
android:background="@color/divider"
|
||||||
|
android:layout_marginVertical="16dp"/>
|
||||||
|
|
||||||
|
<!-- Shots -->
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/label_shots"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:text="Remates"
|
||||||
|
android:textColor="@color/text_secondary"
|
||||||
|
android:textStyle="bold" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
android:gravity="center">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/text_shots_home"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="5"
|
||||||
|
android:textSize="24sp"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:textColor="@color/secondary_color"
|
||||||
|
android:layout_marginEnd="32dp"/>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/text_shots_away"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="3"
|
||||||
|
android:textSize="24sp"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:textColor="@color/secondary_color"
|
||||||
|
android:layout_marginStart="32dp"/>
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
</androidx.cardview.widget.CardView>
|
||||||
|
</LinearLayout>
|
||||||
|
</ScrollView>
|
||||||
33
app/src/main/res/layout/fragment_live_games.xml
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout 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="match_parent"
|
||||||
|
android:background="@color/background_light">
|
||||||
|
|
||||||
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
android:id="@+id/recycler_live_games"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:paddingTop="8dp"
|
||||||
|
android:clipToPadding="false"
|
||||||
|
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/text_no_games"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="Não há jogos ao vivo no momento"
|
||||||
|
android:textSize="16sp"
|
||||||
|
android:textColor="@color/text_secondary"
|
||||||
|
android:visibility="gone"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
66
app/src/main/res/layout/item_club.xml
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.cardview.widget.CardView 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:layout_marginHorizontal="16dp"
|
||||||
|
android:layout_marginVertical="6dp"
|
||||||
|
app:cardBackgroundColor="@color/surface_card"
|
||||||
|
app:cardCornerRadius="12dp"
|
||||||
|
app:cardElevation="2dp">
|
||||||
|
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:padding="16dp">
|
||||||
|
|
||||||
|
<androidx.cardview.widget.CardView
|
||||||
|
android:id="@+id/card_logo"
|
||||||
|
android:layout_width="50dp"
|
||||||
|
android:layout_height="50dp"
|
||||||
|
app:cardCornerRadius="25dp"
|
||||||
|
app:cardElevation="0dp"
|
||||||
|
app:cardBackgroundColor="#F0F0F0"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/image_club_logo"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:scaleType="centerCrop"
|
||||||
|
android:src="@drawable/ic_menu_gallery"
|
||||||
|
android:padding="8dp"/>
|
||||||
|
</androidx.cardview.widget.CardView>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/text_club_name"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="16dp"
|
||||||
|
android:text="Club Name"
|
||||||
|
android:textColor="@color/text_primary"
|
||||||
|
android:textSize="17sp"
|
||||||
|
android:textStyle="bold"
|
||||||
|
app:layout_constraintBottom_toTopOf="@+id/text_club_stadium"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toEndOf="@+id/card_logo"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
app:layout_constraintVertical_chainStyle="packed"/>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/text_club_stadium"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="2dp"
|
||||||
|
android:text="Stadium Name"
|
||||||
|
android:textColor="@color/text_secondary"
|
||||||
|
android:textSize="14sp"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="@+id/text_club_name"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/text_club_name" />
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
</androidx.cardview.widget.CardView>
|
||||||
85
app/src/main/res/layout/item_live_game.xml
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.cardview.widget.CardView 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:layout_marginHorizontal="16dp"
|
||||||
|
android:layout_marginVertical="8dp"
|
||||||
|
app:cardBackgroundColor="@color/surface_card"
|
||||||
|
app:cardCornerRadius="16dp"
|
||||||
|
app:cardElevation="2dp">
|
||||||
|
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:padding="20dp">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/text_game_time"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="45'"
|
||||||
|
android:textColor="@color/live_time"
|
||||||
|
android:textSize="14sp"
|
||||||
|
android:textStyle="bold"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:id="@+id/live_indicator"
|
||||||
|
android:layout_width="8dp"
|
||||||
|
android:layout_height="8dp"
|
||||||
|
android:layout_marginEnd="6dp"
|
||||||
|
android:background="@drawable/shape_circle_live"
|
||||||
|
app:layout_constraintBottom_toBottomOf="@+id/text_game_time"
|
||||||
|
app:layout_constraintEnd_toStartOf="@+id/text_game_time"
|
||||||
|
app:layout_constraintTop_toTopOf="@+id/text_game_time" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/text_home_team"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="12dp"
|
||||||
|
android:gravity="center"
|
||||||
|
android:text="Home Team"
|
||||||
|
android:textColor="@color/text_primary"
|
||||||
|
android:textSize="16sp"
|
||||||
|
android:textStyle="bold"
|
||||||
|
app:layout_constraintEnd_toStartOf="@+id/text_score"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/text_game_time" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/text_score"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginHorizontal="24dp"
|
||||||
|
android:background="@drawable/shape_score_bg"
|
||||||
|
android:paddingHorizontal="16dp"
|
||||||
|
android:paddingVertical="6dp"
|
||||||
|
android:text="2 - 1"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
android:textSize="20sp"
|
||||||
|
android:textStyle="bold"
|
||||||
|
app:layout_constraintBottom_toBottomOf="@+id/text_home_team"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="@+id/text_home_team" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/text_away_team"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:gravity="center"
|
||||||
|
android:text="Away Team"
|
||||||
|
android:textColor="@color/text_primary"
|
||||||
|
android:textSize="16sp"
|
||||||
|
android:textStyle="bold"
|
||||||
|
app:layout_constraintBottom_toBottomOf="@+id/text_home_team"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toEndOf="@+id/text_score"
|
||||||
|
app:layout_constraintTop_toTopOf="@+id/text_home_team" />
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
</androidx.cardview.widget.CardView>
|
||||||
58
app/src/main/res/layout/item_match.xml
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:padding="8dp">
|
||||||
|
|
||||||
|
<!-- Home Team -->
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/text_home_team"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:gravity="end"
|
||||||
|
android:text="Home"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:textColor="@color/text_primary" />
|
||||||
|
|
||||||
|
<!-- Score / Time -->
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginHorizontal="12dp"
|
||||||
|
android:gravity="center"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:minWidth="60dp">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/text_score"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="Vs"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:textColor="@color/secondary_color"
|
||||||
|
android:textSize="16sp" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/text_time"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="15:00"
|
||||||
|
android:textSize="12sp"
|
||||||
|
android:textColor="@color/text_secondary" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<!-- Away Team -->
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/text_away_team"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:gravity="start"
|
||||||
|
android:text="Away"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:textColor="@color/text_primary" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
39
app/src/main/res/layout/item_matchday.xml
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.cardview.widget.CardView 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:layout_marginBottom="16dp"
|
||||||
|
app:cardCornerRadius="12dp"
|
||||||
|
app:cardElevation="4dp"
|
||||||
|
app:contentPadding="0dp">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<!-- Header -->
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/text_matchday_name"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="@color/primary_light"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
android:padding="12dp"
|
||||||
|
android:text="Jornada 1"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:textSize="16sp" />
|
||||||
|
|
||||||
|
<!-- Matches List -->
|
||||||
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
android:id="@+id/recycler_matches"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:nestedScrollingEnabled="false"
|
||||||
|
tools:itemCount="3"
|
||||||
|
tools:listitem="@layout/item_match" xmlns:tools="http://schemas.android.com/tools"/>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</androidx.cardview.widget.CardView>
|
||||||
25
app/src/main/res/layout/item_player.xml
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:padding="16dp"
|
||||||
|
android:gravity="center_vertical">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/image_player_icon"
|
||||||
|
android:layout_width="40dp"
|
||||||
|
android:layout_height="40dp"
|
||||||
|
android:src="@drawable/ic_menu_camera"
|
||||||
|
android:contentDescription="Player Icon"
|
||||||
|
android:layout_marginEnd="16dp"/>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/text_player_name"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="Player Name"
|
||||||
|
android:textSize="16sp"
|
||||||
|
android:textStyle="bold" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
59
app/src/main/res/layout/item_standing.xml
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:paddingVertical="16dp"
|
||||||
|
android:paddingHorizontal="4dp"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:background="?attr/selectableItemBackground">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/text_position"
|
||||||
|
android:layout_width="40dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="1"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:textColor="@color/black"
|
||||||
|
android:textSize="16sp" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/text_team_name"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:text="Team Name"
|
||||||
|
android:textColor="@color/black"
|
||||||
|
android:textSize="16sp"
|
||||||
|
android:textStyle="normal" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/text_played"
|
||||||
|
android:layout_width="40dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:gravity="center"
|
||||||
|
android:text="P"
|
||||||
|
android:textColor="@color/text_secondary"
|
||||||
|
android:textSize="14sp" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/text_points"
|
||||||
|
android:layout_width="40dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:gravity="center"
|
||||||
|
android:text="Pts"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:textColor="@color/black"
|
||||||
|
android:textSize="14sp" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="1dp"
|
||||||
|
android:background="#F5F5F5"/>
|
||||||
|
</LinearLayout>
|
||||||
@@ -1,35 +1,50 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="@dimen/nav_header_height"
|
android:layout_height="200dp"
|
||||||
android:background="@drawable/side_nav_bar"
|
android:background="@drawable/ic_header_login_bg"
|
||||||
android:gravity="bottom"
|
android:gravity="top"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
android:paddingLeft="@dimen/activity_horizontal_margin"
|
android:paddingLeft="@dimen/activity_horizontal_margin"
|
||||||
android:paddingTop="@dimen/activity_vertical_margin"
|
android:paddingTop="@dimen/activity_vertical_margin"
|
||||||
android:paddingRight="@dimen/activity_horizontal_margin"
|
android:paddingRight="@dimen/activity_horizontal_margin"
|
||||||
android:paddingBottom="@dimen/activity_vertical_margin"
|
android:paddingBottom="@dimen/activity_vertical_margin"
|
||||||
android:theme="@style/ThemeOverlay.AppCompat.Dark">
|
android:theme="@style/ThemeOverlay.AppCompat.Light">
|
||||||
|
|
||||||
|
<androidx.cardview.widget.CardView
|
||||||
|
android:layout_width="80dp"
|
||||||
|
android:layout_height="80dp"
|
||||||
|
android:layout_marginTop="10dp"
|
||||||
|
app:cardCornerRadius="40dp"
|
||||||
|
app:cardBackgroundColor="@color/white"
|
||||||
|
app:cardElevation="4dp">
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/imageView"
|
android:id="@+id/imageView"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="match_parent"
|
||||||
android:contentDescription="@string/nav_header_desc"
|
android:contentDescription="@string/nav_header_desc"
|
||||||
android:paddingTop="@dimen/nav_header_vertical_spacing"
|
android:scaleType="centerCrop"
|
||||||
app:srcCompat="@mipmap/ic_launcher_round" />
|
app:srcCompat="@mipmap/ic_launcher_round" />
|
||||||
|
</androidx.cardview.widget.CardView>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
|
android:id="@+id/textViewName"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:paddingTop="@dimen/nav_header_vertical_spacing"
|
android:paddingTop="4dp"
|
||||||
android:text="@string/nav_header_title"
|
android:text="@string/nav_header_title"
|
||||||
android:textAppearance="@style/TextAppearance.AppCompat.Body1" />
|
android:textAppearance="@style/TextAppearance.AppCompat.Body1"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
android:textSize="20sp"
|
||||||
|
android:textStyle="bold" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/textView"
|
android:id="@+id/textViewSubtitle"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="@string/nav_header_subtitle" />
|
android:text="@string/nav_header_subtitle"
|
||||||
|
android:textColor="@color/background_light"
|
||||||
|
android:textSize="14sp" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
@@ -12,6 +12,14 @@
|
|||||||
android:id="@+id/nav_gallery"
|
android:id="@+id/nav_gallery"
|
||||||
android:icon="@drawable/ic_menu_gallery"
|
android:icon="@drawable/ic_menu_gallery"
|
||||||
android:title="@string/menu_gallery" />
|
android:title="@string/menu_gallery" />
|
||||||
|
<item
|
||||||
|
android:id="@+id/nav_live_games"
|
||||||
|
android:icon="@android:drawable/ic_menu_view"
|
||||||
|
android:title="@string/menu_live_games" />
|
||||||
|
<item
|
||||||
|
android:id="@+id/nav_clubs"
|
||||||
|
android:icon="@android:drawable/ic_menu_my_calendar"
|
||||||
|
android:title="@string/menu_clubs" />
|
||||||
<item
|
<item
|
||||||
android:id="@+id/nav_definicoes"
|
android:id="@+id/nav_definicoes"
|
||||||
android:icon="@android:drawable/ic_menu_preferences"
|
android:icon="@android:drawable/ic_menu_preferences"
|
||||||
|
|||||||
BIN
app/src/main/res/mipmap-hdpi/ic_launcher.png
Normal file
|
After Width: | Height: | Size: 6.8 KiB |
|
Before Width: | Height: | Size: 1.4 KiB |
BIN
app/src/main/res/mipmap-hdpi/ic_launcher_round.png
Normal file
|
After Width: | Height: | Size: 6.8 KiB |
|
Before Width: | Height: | Size: 2.8 KiB |
BIN
app/src/main/res/mipmap-mdpi/ic_launcher.png
Normal file
|
After Width: | Height: | Size: 3.3 KiB |
|
Before Width: | Height: | Size: 982 B |
BIN
app/src/main/res/mipmap-mdpi/ic_launcher_round.png
Normal file
|
After Width: | Height: | Size: 3.3 KiB |
|
Before Width: | Height: | Size: 1.7 KiB |
BIN
app/src/main/res/mipmap-xhdpi/ic_launcher.png
Normal file
|
After Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 1.9 KiB |
BIN
app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
Normal file
|
After Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 3.8 KiB |
BIN
app/src/main/res/mipmap-xxhdpi/ic_launcher.png
Normal file
|
After Width: | Height: | Size: 25 KiB |
|
Before Width: | Height: | Size: 2.8 KiB |
BIN
app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
Normal file
|
After Width: | Height: | Size: 25 KiB |
|
Before Width: | Height: | Size: 5.8 KiB |
BIN
app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
Normal file
|
After Width: | Height: | Size: 42 KiB |
|
Before Width: | Height: | Size: 3.8 KiB |
BIN
app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
Normal file
|
After Width: | Height: | Size: 42 KiB |
|
Before Width: | Height: | Size: 7.6 KiB |
@@ -22,4 +22,60 @@
|
|||||||
android:name="com.example.vdcscore.ui.definicoes.DefinicoesFragment"
|
android:name="com.example.vdcscore.ui.definicoes.DefinicoesFragment"
|
||||||
android:label="@string/menu_definicoes"
|
android:label="@string/menu_definicoes"
|
||||||
tools:layout="@layout/fragment_definicoes" />
|
tools:layout="@layout/fragment_definicoes" />
|
||||||
|
|
||||||
|
<fragment
|
||||||
|
android:id="@+id/nav_live_games"
|
||||||
|
android:name="com.example.vdcscore.ui.livegames.LiveGamesFragment"
|
||||||
|
android:label="@string/menu_live_games"
|
||||||
|
tools:layout="@layout/fragment_live_games">
|
||||||
|
<action
|
||||||
|
android:id="@+id/action_nav_live_games_to_nav_live_game_detail"
|
||||||
|
app:destination="@id/nav_live_game_detail" />
|
||||||
|
</fragment>
|
||||||
|
|
||||||
|
<fragment
|
||||||
|
android:id="@+id/nav_live_game_detail"
|
||||||
|
android:name="com.example.vdcscore.ui.livegames.LiveGameDetailFragment"
|
||||||
|
android:label="@string/title_live_game_detail"
|
||||||
|
tools:layout="@layout/fragment_live_game_detail" />
|
||||||
|
|
||||||
|
<fragment
|
||||||
|
android:id="@+id/nav_clubs"
|
||||||
|
android:name="com.example.vdcscore.ui.clubs.ClubsFragment"
|
||||||
|
android:label="@string/menu_clubs"
|
||||||
|
tools:layout="@layout/fragment_clubs">
|
||||||
|
<action
|
||||||
|
android:id="@+id/action_nav_clubs_to_nav_club_detail"
|
||||||
|
app:destination="@id/nav_club_detail" />
|
||||||
|
</fragment>
|
||||||
|
|
||||||
|
<fragment
|
||||||
|
android:id="@+id/nav_club_detail"
|
||||||
|
android:name="com.example.vdcscore.ui.clubs.ClubDetailFragment"
|
||||||
|
android:label="Detalhes do Clube"
|
||||||
|
tools:layout="@layout/fragment_club_detail">
|
||||||
|
<argument
|
||||||
|
android:name="clubId"
|
||||||
|
app:argType="string" />
|
||||||
|
<argument
|
||||||
|
android:name="escalao"
|
||||||
|
app:argType="string" />
|
||||||
|
<action
|
||||||
|
android:id="@+id/action_nav_club_detail_to_nav_club_players"
|
||||||
|
app:destination="@id/nav_club_players" />
|
||||||
|
</fragment>
|
||||||
|
|
||||||
|
<fragment
|
||||||
|
android:id="@+id/nav_club_players"
|
||||||
|
android:name="com.example.vdcscore.ui.clubs.ClubPlayersFragment"
|
||||||
|
android:label="Jogadores"
|
||||||
|
tools:layout="@layout/fragment_club_players">
|
||||||
|
<argument
|
||||||
|
android:name="clubId"
|
||||||
|
app:argType="string" />
|
||||||
|
<argument
|
||||||
|
android:name="escalao"
|
||||||
|
app:argType="string" />
|
||||||
|
</fragment>
|
||||||
|
|
||||||
</navigation>
|
</navigation>
|
||||||
@@ -1,7 +1,29 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources xmlns:tools="http://schemas.android.com/tools">
|
<resources xmlns:tools="http://schemas.android.com/tools">
|
||||||
<!-- Base application theme. -->
|
<!-- Base application theme. -->
|
||||||
<style name="Base.Theme.VdcScore" parent="Theme.Material3.DayNight.NoActionBar">
|
<style name="Base.Theme.VdcScore" parent="Theme.Material3.DayNight.NoActionBar">
|
||||||
<!-- Customize your dark theme here. -->
|
<!-- Customize your dark theme here. -->
|
||||||
<!-- <item name="colorPrimary">@color/my_dark_primary</item> -->
|
<!-- Force White Status Bar even in Dark Mode -->
|
||||||
|
<item name="android:statusBarColor">@color/white</item>
|
||||||
|
<item name="android:windowLightStatusBar">true</item>
|
||||||
|
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
|
||||||
|
|
||||||
|
<item name="colorPrimary">@color/primary_color</item>
|
||||||
|
<item name="colorPrimaryVariant">@color/primary_dark</item>
|
||||||
|
<item name="colorOnPrimary">@color/white</item>
|
||||||
|
<item name="colorSecondary">@color/secondary_color</item>
|
||||||
|
<item name="colorSecondaryVariant">@color/secondary_dark</item>
|
||||||
|
<item name="colorOnSecondary">@color/white</item>
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<style name="Theme.VdcScore" parent="Base.Theme.VdcScore" />
|
||||||
|
|
||||||
|
<style name="Theme.VdcScore.NoActionBar">
|
||||||
|
<item name="windowActionBar">false</item>
|
||||||
|
<item name="windowNoTitle">true</item>
|
||||||
|
<!-- Explicitly enforce status bar settings here too -->
|
||||||
|
<item name="android:statusBarColor">@color/white</item>
|
||||||
|
<item name="android:windowLightStatusBar">true</item>
|
||||||
|
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
|
||||||
</style>
|
</style>
|
||||||
</resources>
|
</resources>
|
||||||
@@ -2,4 +2,27 @@
|
|||||||
<resources>
|
<resources>
|
||||||
<color name="black">#FF000000</color>
|
<color name="black">#FF000000</color>
|
||||||
<color name="white">#FFFFFFFF</color>
|
<color name="white">#FFFFFFFF</color>
|
||||||
|
|
||||||
|
<!-- Minimalist Palette -->
|
||||||
|
<color name="primary_color">#000000</color> <!-- Black -->
|
||||||
|
<color name="primary_light">#404040</color> <!-- Dark Grey -->
|
||||||
|
<color name="primary_dark">#000000</color>
|
||||||
|
|
||||||
|
<color name="secondary_color">#212121</color> <!-- Dark Grey Accent -->
|
||||||
|
<color name="secondary_light">#484848</color>
|
||||||
|
<color name="secondary_dark">#000000</color>
|
||||||
|
|
||||||
|
<color name="live_indicator">#00E676</color> <!-- Bright Green (Keep for utility) -->
|
||||||
|
<color name="live_time">#FF1744</color> <!-- Red for time (Keep for utility) -->
|
||||||
|
|
||||||
|
<color name="background_light">#FFFFFF</color> <!-- Pure White Background -->
|
||||||
|
<color name="surface_light">#FFFFFF</color>
|
||||||
|
<color name="surface_card">#FFFFFF</color> <!-- White Card -->
|
||||||
|
|
||||||
|
<color name="text_primary">#212121</color> <!-- Almost Black -->
|
||||||
|
<color name="text_secondary">#757575</color> <!-- Grey -->
|
||||||
|
<color name="text_on_primary">#FFFFFF</color>
|
||||||
|
|
||||||
|
<color name="divider">#EEEEEE</color> <!-- Very light grey divider -->
|
||||||
|
<color name="input_background">#F5F5F5</color> <!-- Light grey for inputs/cards if needed -->
|
||||||
</resources>
|
</resources>
|
||||||