mudancas para por a base de dados das equipas

This commit is contained in:
2026-01-23 16:23:06 +00:00
parent f034364a41
commit 750e91538c
9 changed files with 418 additions and 68 deletions

View File

@@ -1,51 +1,136 @@
package com.example.vdcscore.models;
import com.google.firebase.database.PropertyName;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class Club {
@PropertyName("id")
private String id;
@PropertyName("nome")
private String name;
@PropertyName("logoUrl")
private String logoUrl;
@PropertyName("campo")
private String stadium;
// Stats could be here or in a separate object, keeping basic info here
@PropertyName("ano fundacao")
private String foundationYear;
@PropertyName("morada")
private String address;
@PropertyName("presidente")
private String president;
@PropertyName("jogadores")
private Map<String, Player> players;
public Club() {
// Default constructor for Firebase
players = new HashMap<>();
}
public Club(String id, String name, String logoUrl, String stadium) {
public Club(String id, String name, String logoUrl, String stadium, String foundationYear, String address,
String president) {
this.id = id;
this.name = name;
this.logoUrl = logoUrl;
this.stadium = stadium;
this.foundationYear = foundationYear;
this.address = address;
this.president = president;
this.players = new HashMap<>();
}
@PropertyName("id")
public String getId() {
return id;
}
@PropertyName("id")
public void setId(String id) {
this.id = id;
}
@PropertyName("nome")
public String getName() {
return name;
}
@PropertyName("nome")
public void setName(String name) {
this.name = name;
}
@PropertyName("logoUrl")
public String getLogoUrl() {
return logoUrl;
}
@PropertyName("logoUrl")
public void setLogoUrl(String logoUrl) {
this.logoUrl = logoUrl;
}
@PropertyName("campo")
public String getStadium() {
return stadium;
}
@PropertyName("campo")
public void setStadium(String stadium) {
this.stadium = stadium;
}
@PropertyName("ano fundacao")
public String getFoundationYear() {
return foundationYear;
}
@PropertyName("ano fundacao")
public void setFoundationYear(String 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 Map<String, Player> getPlayersMap() {
return players;
}
@PropertyName("jogadores")
public void setPlayersMap(Map<String, Player> players) {
this.players = players;
}
public List<Player> getPlayersList() {
if (players == null)
return new ArrayList<>();
return new ArrayList<>(players.values());
}
}

View File

@@ -0,0 +1,40 @@
package com.example.vdcscore.models;
import com.google.firebase.database.PropertyName;
public class Player {
@PropertyName("id")
private String id;
@PropertyName("nome")
private String nome;
public Player() {
// Default constructor required for calls to DataSnapshot.getValue(Player.class)
}
public Player(String id, String nome) {
this.id = id;
this.nome = nome;
}
@PropertyName("id")
public String getId() {
return id;
}
@PropertyName("id")
public void setId(String id) {
this.id = id;
}
@PropertyName("nome")
public String getNome() {
return nome;
}
@PropertyName("nome")
public void setNome(String nome) {
this.nome = nome;
}
}

View File

@@ -1,41 +0,0 @@
package com.example.vdcscore.ui.clubs;
public class Club {
private String name;
private String stadium;
private String logoUrl;
public Club() {
// Default constructor required for calls to DataSnapshot.getValue(Club.class)
}
public Club(String name, String stadium, String logoUrl) {
this.name = name;
this.stadium = stadium;
this.logoUrl = logoUrl;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getStadium() {
return stadium;
}
public void setStadium(String stadium) {
this.stadium = stadium;
}
public String getLogoUrl() {
return logoUrl;
}
public void setLogoUrl(String logoUrl) {
this.logoUrl = logoUrl;
}
}

View File

@@ -10,15 +10,22 @@ import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
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 ClubAdapter(List<Club> clubs) {
public interface OnItemClickListener {
void onItemClick(Club club);
}
public ClubAdapter(List<Club> clubs, OnItemClickListener listener) {
mClubs = clubs;
mListener = listener;
}
@NonNull
@@ -32,7 +39,7 @@ public class ClubAdapter extends RecyclerView.Adapter<ClubAdapter.ClubViewHolder
@Override
public void onBindViewHolder(@NonNull ClubViewHolder holder, int position) {
Club club = mClubs.get(position);
holder.bind(club);
holder.bind(club, mListener);
}
@Override
@@ -52,11 +59,12 @@ public class ClubAdapter extends RecyclerView.Adapter<ClubAdapter.ClubViewHolder
logo = itemView.findViewById(R.id.image_club_logo);
}
public void bind(final Club club) {
public void bind(final Club club, final OnItemClickListener listener) {
name.setText(club.getName());
stadium.setText(club.getStadium());
// TODO: Load image from logoUrl using a library like Glide or Picasso
// For now we leave the default placeholder
// TODO: Load image from logoUrl using a library like Glide
itemView.setOnClickListener(v -> listener.onItemClick(club));
}
}
}

View File

@@ -0,0 +1,93 @@
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.FragmentClubDetailBinding;
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 ClubDetailFragment extends Fragment {
private FragmentClubDetailBinding binding;
private DatabaseReference mDatabase;
private String clubId;
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
clubId = getArguments().getString("clubId");
}
}
@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);
binding.recyclerPlayers.setLayoutManager(new LinearLayoutManager(getContext()));
if (clubId != null) {
mDatabase = FirebaseDatabase.getInstance().getReference().child("clubes").child(clubId); // Updated to
// 'clubes'
loadClubDetails();
}
}
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(club.getFoundationYear());
binding.textDetailPresident.setText(club.getPresident());
binding.textDetailStadium.setText(club.getStadium());
binding.textDetailAddress.setText(club.getAddress());
List<Player> playerList = club.getPlayersList();
PlayerAdapter adapter = new PlayerAdapter(playerList);
binding.recyclerPlayers.setAdapter(adapter);
}
}
@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;
}
}

View File

@@ -10,11 +10,13 @@ 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;
@@ -35,7 +37,8 @@ public class ClubsFragment extends Fragment {
binding = FragmentClubsBinding.inflate(inflater, container, false);
View root = binding.getRoot();
mDatabase = FirebaseDatabase.getInstance().getReference().child("clubs");
mDatabase = FirebaseDatabase.getInstance().getReference().child("clubes"); // Changed to 'clubes' as per
// screenshot
RecyclerView recyclerView = binding.recyclerClubs;
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
@@ -49,42 +52,37 @@ public class ClubsFragment extends Fragment {
List<Club> clubs = new ArrayList<>();
for (DataSnapshot postSnapshot : snapshot.getChildren()) {
Club club = postSnapshot.getValue(Club.class);
clubs.add(club);
if (club != null) {
clubs.add(club);
}
}
ClubAdapter adapter = new ClubAdapter(clubs);
ClubAdapter adapter = new ClubAdapter(clubs, club -> {
Bundle bundle = new Bundle();
bundle.putString("clubId", club.getId());
Navigation.findNavController(root).navigate(R.id.action_nav_clubs_to_nav_club_detail, bundle);
});
recyclerView.setAdapter(adapter);
progressBar.setVisibility(View.GONE);
if (clubs.isEmpty()) {
// Add mock data if empty for demonstration
addMockClubsIfEmpty();
// 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());
Toast.makeText(getContext(), "Failed to load clubs.", Toast.LENGTH_SHORT).show();
progressBar.setVisibility(View.GONE);
if (getContext() != null) {
Toast.makeText(getContext(), "Failed to load clubs.", Toast.LENGTH_SHORT).show();
}
binding.progressBar.setVisibility(View.GONE);
}
});
return root;
}
private void addMockClubsIfEmpty() {
// If database is empty, optional helper to add data?
// For now, let's keep it strictly reading from Firebase or showing empty state.
// But to ensure user sees something if they haven't set up DB yet:
List<Club> mockClubs = new ArrayList<>();
mockClubs.add(new Club("VDC", "Campo Principal", ""));
mockClubs.add(new Club("Benfica", "Estádio da Luz", ""));
ClubAdapter adapter = new ClubAdapter(mockClubs);
binding.recyclerClubs.setAdapter(adapter);
Toast.makeText(getContext(), "No clubs found in Firebase. Showing mock data.", Toast.LENGTH_LONG).show();
}
@Override
public void onDestroyView() {
super.onDestroyView();

View File

@@ -0,0 +1,55 @@
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) {
name.setText(player.getNome());
}
}
}

View File

@@ -0,0 +1,87 @@
<?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"
tools:context=".ui.clubs.ClubDetailFragment">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="16dp">
<TextView
android:id="@+id/text_detail_club_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Club Name"
android:textSize="24sp"
android:textStyle="bold"
android:layout_marginBottom="16dp"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Fundado em:"
android:textStyle="bold"/>
<TextView
android:id="@+id/text_detail_foundation"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="1900"
android:layout_marginBottom="8dp"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Presidente:"
android:textStyle="bold"/>
<TextView
android:id="@+id/text_detail_president"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Nome do Presidente"
android:layout_marginBottom="8dp"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Estádio:"
android:textStyle="bold"/>
<TextView
android:id="@+id/text_detail_stadium"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Nome do Estádio"
android:layout_marginBottom="8dp"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Morada:"
android:textStyle="bold"/>
<TextView
android:id="@+id/text_detail_address"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Morada do Clube"
android:layout_marginBottom="24dp"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Jogadores"
android:textSize="20sp"
android:textStyle="bold"
android:layout_marginBottom="8dp"/>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_players"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:nestedScrollingEnabled="false"/>
</LinearLayout>
</androidx.core.widget.NestedScrollView>

View 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>