erro
This commit is contained in:
@@ -23,13 +23,13 @@ public class LeagueHelper {
|
||||
}
|
||||
|
||||
public static final LeagueInfo[] LEAGUES = {
|
||||
new LeagueInfo("Bronze", 0, 499, R.drawable.ic_trophy_bronze, "#8D6E63", "• Badge Bronze"),
|
||||
new LeagueInfo("Prata", 500, 1499, R.drawable.ic_trophy_silver, "#B0BEC5", "• Badge Prata\n• Moldura Simples"),
|
||||
new LeagueInfo("Ouro", 1500, 2999, R.drawable.ic_trophy_gold, "#FFD54F", "• Badge Ouro\n• Moldura Dourada"),
|
||||
new LeagueInfo("Platina", 3000, 5999, R.drawable.ic_trophy_platinum, "#4FC3F7", "• Badge Platina\n• Tema Azul"),
|
||||
new LeagueInfo("Diamante", 6000, 9999, R.drawable.ic_trophy_diamond, "#1E88E5", "• Badge Diamante\n• Moldura Diamante"),
|
||||
new LeagueInfo("Mestre", 10000, 14999, R.drawable.ic_trophy_master, "#7C3AED", "• Badge Mestre\n• Tema Roxo Premium"),
|
||||
new LeagueInfo("Lenda", 15000, Integer.MAX_VALUE, R.drawable.ic_trophy_legend, "#D81B60", "• Badge Lenda\n• Moldura Lendária")
|
||||
new LeagueInfo("Bronze", 0, 499, R.drawable.ic_trophy_bronze, "#8D6E63", "Estás a começar a tua jornada!"),
|
||||
new LeagueInfo("Prata", 500, 1499, R.drawable.ic_trophy_silver, "#B0BEC5", "A consistência está a dar frutos."),
|
||||
new LeagueInfo("Ouro", 1500, 2999, R.drawable.ic_trophy_gold, "#FFD54F", "Um verdadeiro guerreiro do foco!"),
|
||||
new LeagueInfo("Platina", 3000, 4999, R.drawable.ic_trophy_platinum, "#4FC3F7", "Elite da produtividade."),
|
||||
new LeagueInfo("Diamante", 5000, 7499, R.drawable.ic_trophy_diamond, "#1E88E5", "Inquebrável e imparável."),
|
||||
new LeagueInfo("Mestre", 7500, 9999, R.drawable.ic_trophy_master, "#7C3AED", "Mestre absoluto da Fluxup."),
|
||||
new LeagueInfo("Lenda", 10000, Integer.MAX_VALUE, R.drawable.ic_trophy_legend, "#D81B60", "Uma lenda viva da disciplina!")
|
||||
};
|
||||
|
||||
public static LeagueInfo getCurrentLeague(int totalXp) {
|
||||
|
||||
@@ -1,29 +1,61 @@
|
||||
package com.fluxup.app;
|
||||
|
||||
import android.animation.ObjectAnimator;
|
||||
import android.content.Intent;
|
||||
|
||||
import android.graphics.Color;
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.animation.DecelerateInterpolator;
|
||||
import android.widget.ImageButton;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.TextView;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.GridLayout;
|
||||
import android.widget.LinearLayout;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.cardview.widget.CardView;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.github.mikephil.charting.charts.LineChart;
|
||||
import com.github.mikephil.charting.components.XAxis;
|
||||
import com.github.mikephil.charting.data.Entry;
|
||||
import com.github.mikephil.charting.data.LineData;
|
||||
import com.github.mikephil.charting.data.LineDataSet;
|
||||
import com.github.mikephil.charting.formatter.IndexAxisValueFormatter;
|
||||
import com.google.firebase.auth.FirebaseUser;
|
||||
import com.google.firebase.firestore.ListenerRegistration;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
public class ProfileFragment extends Fragment {
|
||||
|
||||
private TextView tvProfileName, tvProfileHandle, tvProfileSince, tvProfileBio;
|
||||
private TextView tvStatTopXP, tvStatFollowing, tvStatFollowers, tvStatActiveDays;
|
||||
private TextView tvProfileName, tvProfileHandle;
|
||||
private ImageView ivProfileAvatar, ivLeagueBadgeSmall, ivLeagueIcon;
|
||||
private TextView tvUserLevel, tvXpFraction, tvLeagueName, tvLeagueMotivation, tvConsistencyPhrase;
|
||||
private ProgressBar pbXpLevel;
|
||||
private RecyclerView rvMiniCalendar;
|
||||
private LineChart weeklyChart;
|
||||
private GridLayout badgesGrid;
|
||||
private LinearLayout friendsListContainer;
|
||||
|
||||
private View statTotalTasks, statBestStreak, statFocusSessions, statTotalFocus, statDaysCompleted, statDailyAvg;
|
||||
|
||||
private ListenerRegistration userListener, friendsListener;
|
||||
private View view;
|
||||
private Usuario currentUser;
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
@@ -41,76 +73,269 @@ public class ProfileFragment extends Fragment {
|
||||
private void initViews(View view) {
|
||||
tvProfileName = view.findViewById(R.id.tvProfileName);
|
||||
tvProfileHandle = view.findViewById(R.id.tvProfileHandle);
|
||||
tvProfileSince = view.findViewById(R.id.tvProfileSince);
|
||||
tvProfileBio = view.findViewById(R.id.tvProfileBio);
|
||||
tvStatTopXP = view.findViewById(R.id.tvStatTopXP);
|
||||
tvStatFollowing = view.findViewById(R.id.tvStatFollowing);
|
||||
tvStatFollowers = view.findViewById(R.id.tvStatFollowers);
|
||||
tvStatActiveDays = view.findViewById(R.id.tvStatActiveDays);
|
||||
ivProfileAvatar = view.findViewById(R.id.ivProfileAvatar);
|
||||
ivLeagueBadgeSmall = view.findViewById(R.id.ivLeagueBadgeSmall);
|
||||
ivLeagueIcon = view.findViewById(R.id.ivLeagueIcon);
|
||||
|
||||
tvUserLevel = view.findViewById(R.id.tvUserLevel);
|
||||
tvXpFraction = view.findViewById(R.id.tvXpFraction);
|
||||
tvLeagueName = view.findViewById(R.id.tvLeagueName);
|
||||
tvLeagueMotivation = view.findViewById(R.id.tvLeagueMotivation);
|
||||
tvConsistencyPhrase = view.findViewById(R.id.tvConsistencyPhrase);
|
||||
|
||||
pbXpLevel = view.findViewById(R.id.pbXpLevel);
|
||||
rvMiniCalendar = view.findViewById(R.id.rvMiniCalendar);
|
||||
weeklyChart = view.findViewById(R.id.weeklyChart);
|
||||
|
||||
badgesGrid = view.findViewById(R.id.badgesGrid);
|
||||
friendsListContainer = view.findViewById(R.id.friendsListContainer);
|
||||
|
||||
statTotalTasks = view.findViewById(R.id.statTotalTasks);
|
||||
statBestStreak = view.findViewById(R.id.statBestStreak);
|
||||
statFocusSessions = view.findViewById(R.id.statFocusSessions);
|
||||
statTotalFocus = view.findViewById(R.id.statTotalFocus);
|
||||
statDaysCompleted = view.findViewById(R.id.statDaysCompleted);
|
||||
statDailyAvg = view.findViewById(R.id.statDailyAvg);
|
||||
|
||||
setupStatItems();
|
||||
}
|
||||
|
||||
private void setupStatItems() {
|
||||
setStatMeta(statTotalTasks, "🎯", "Tarefas");
|
||||
setStatMeta(statBestStreak, "🔥", "Recorde");
|
||||
setStatMeta(statFocusSessions, "🧠", "Sessões");
|
||||
setStatMeta(statTotalFocus, "⏱️", "Total Foco");
|
||||
setStatMeta(statDaysCompleted, "📅", "Dias");
|
||||
setStatMeta(statDailyAvg, "📈", "Média/Dia");
|
||||
}
|
||||
|
||||
private void setStatMeta(View statView, String icon, String label) {
|
||||
if (statView == null) return;
|
||||
((TextView) statView.findViewById(R.id.tvStatIcon)).setText(icon);
|
||||
((TextView) statView.findViewById(R.id.tvStatLabel)).setText(label);
|
||||
}
|
||||
|
||||
private void setupListeners(View view) {
|
||||
view.findViewById(R.id.btnEditProfile).setOnClickListener(v -> {
|
||||
startActivity(new Intent(getActivity(), SettingsActivity.class));
|
||||
});
|
||||
// Edit Profile / Settings
|
||||
View btnEditProfile = view.findViewById(R.id.btnEditProfile);
|
||||
if (btnEditProfile != null) {
|
||||
btnEditProfile.setOnClickListener(v -> {
|
||||
startActivity(new Intent(getActivity(), SettingsActivity.class));
|
||||
});
|
||||
}
|
||||
|
||||
// Add Friends (+)
|
||||
View btnAddFriends = view.findViewById(R.id.btnAddFriends);
|
||||
if (btnAddFriends != null) {
|
||||
btnAddFriends.setOnClickListener(v -> startActivity(new Intent(getActivity(), MyFriendsActivity.class)));
|
||||
}
|
||||
|
||||
// View All Friends
|
||||
View btnViewAllFriends = view.findViewById(R.id.btnViewAllFriends);
|
||||
if (btnViewAllFriends != null) {
|
||||
btnViewAllFriends.setOnClickListener(v -> startActivity(new Intent(getActivity(), MyFriendsActivity.class)));
|
||||
}
|
||||
|
||||
// Find Friends (ADICIONAR AMIGOS)
|
||||
View btnFindFriends = view.findViewById(R.id.btnFindFriends);
|
||||
if (btnFindFriends != null) {
|
||||
btnFindFriends.setOnClickListener(v -> startActivity(new Intent(getActivity(), MyFriendsActivity.class)));
|
||||
}
|
||||
|
||||
view.findViewById(R.id.btnLogout).setOnClickListener(v -> {
|
||||
AuthManager.getInstance().logout();
|
||||
Intent intent = new Intent(getActivity(), LoginActivity.class);
|
||||
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
|
||||
startActivity(intent);
|
||||
});
|
||||
}
|
||||
// View All Badges
|
||||
View btnViewAllBadges = view.findViewById(R.id.btnViewAllBadges);
|
||||
if (btnViewAllBadges != null) {
|
||||
btnViewAllBadges.setOnClickListener(v -> startActivity(new Intent(getActivity(), TrophiesActivity.class)));
|
||||
}
|
||||
|
||||
private void startObservingUser() {
|
||||
FirebaseUser currentUser = AuthManager.getInstance().getCurrentUser();
|
||||
if (currentUser != null) {
|
||||
userListener = FirestoreManager.getInstance().observeUser(currentUser.getUid(), user -> {
|
||||
if (getContext() == null || view == null) return;
|
||||
updateStats(view, user);
|
||||
tvProfileName.setText(user.usuario);
|
||||
tvProfileHandle.setText(user.handle);
|
||||
String year = (user.created_at != null && user.created_at.length() >= 4) ? user.created_at.substring(0, 4) : "2024";
|
||||
tvProfileSince.setText("Aqui desde " + year);
|
||||
tvProfileBio.setText(user.bio == null || user.bio.isEmpty() ? "Sem bio definida." : user.bio);
|
||||
|
||||
tvStatTopXP.setText(String.valueOf(user.xp));
|
||||
tvStatFollowing.setText(String.valueOf(user.following));
|
||||
tvStatFollowers.setText(String.valueOf(user.followers));
|
||||
tvStatActiveDays.setText(String.valueOf(user.dias_ativos));
|
||||
|
||||
renderBadges(user);
|
||||
// Logout
|
||||
View btnLogout = view.findViewById(R.id.btnLogout);
|
||||
if (btnLogout != null) {
|
||||
btnLogout.setOnClickListener(v -> {
|
||||
AuthManager.getInstance().logout();
|
||||
Intent intent = new Intent(getActivity(), LoginActivity.class);
|
||||
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
|
||||
startActivity(intent);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void updateStats(View view, Usuario user) {
|
||||
setStat(view.findViewById(R.id.statStreak), "🔥", String.valueOf(user.streak), "Ofensiva");
|
||||
setStat(view.findViewById(R.id.statLeague), "🏆", user.league != null ? user.league : "Bronze", "Liga");
|
||||
setStat(view.findViewById(R.id.statXP), "⚡", String.valueOf(user.xp), "Total XP");
|
||||
setStat(view.findViewById(R.id.statFocusTime), "⏱️", user.tempo_foco_total + "m", "Foco");
|
||||
private void startObservingUser() {
|
||||
FirebaseUser fUser = AuthManager.getInstance().getCurrentUser();
|
||||
if (fUser != null) {
|
||||
userListener = FirestoreManager.getInstance().observeUser(fUser.getUid(), user -> {
|
||||
if (getContext() == null || view == null || user == null) return;
|
||||
this.currentUser = user;
|
||||
|
||||
updateBasicInfo(user);
|
||||
updateXpBar(user);
|
||||
updateLeagueCard(user);
|
||||
updateRealStats(user);
|
||||
updateMiniCalendar(user);
|
||||
updateWeeklyChart(user);
|
||||
renderBadges(user);
|
||||
updateMotivation(user);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void setStat(View statView, String icon, String value, String label) {
|
||||
private void updateBasicInfo(Usuario user) {
|
||||
tvProfileName.setText(user.usuario);
|
||||
tvProfileHandle.setText(user.handle);
|
||||
}
|
||||
|
||||
private void updateXpBar(Usuario user) {
|
||||
LeagueHelper.LeagueInfo current = LeagueHelper.getCurrentLeague(user.xp);
|
||||
LeagueHelper.LeagueInfo next = LeagueHelper.getNextLeague(user.xp);
|
||||
|
||||
int currentLevel = calculateLevel(user.xp);
|
||||
tvUserLevel.setText("Nível " + currentLevel);
|
||||
|
||||
int levelStartXp = getLevelStartXp(currentLevel);
|
||||
int levelEndXp = getLevelStartXp(currentLevel + 1);
|
||||
int progressInLevel = user.xp - levelStartXp;
|
||||
int levelXpSpan = levelEndXp - levelStartXp;
|
||||
|
||||
tvXpFraction.setText(user.xp + " / " + levelEndXp + " XP");
|
||||
|
||||
int progressPercent = (int) ((progressInLevel * 100.0f) / levelXpSpan);
|
||||
|
||||
// Animate Progress Bar
|
||||
ObjectAnimator.ofInt(pbXpLevel, "progress", pbXpLevel.getProgress(), progressPercent)
|
||||
.setDuration(1000)
|
||||
.setInterpolator(new DecelerateInterpolator())
|
||||
.start();
|
||||
}
|
||||
|
||||
private int calculateLevel(int totalXp) {
|
||||
// Simple formula: Level = sqrt(xp/100)
|
||||
return (int) Math.floor(Math.sqrt(totalXp / 50.0)) + 1;
|
||||
}
|
||||
|
||||
private int getLevelStartXp(int level) {
|
||||
if (level <= 1) return 0;
|
||||
return (int) (Math.pow(level - 1, 2) * 50);
|
||||
}
|
||||
|
||||
private void updateLeagueCard(Usuario user) {
|
||||
LeagueHelper.LeagueInfo current = LeagueHelper.getCurrentLeague(user.xp);
|
||||
LeagueHelper.LeagueInfo next = LeagueHelper.getNextLeague(user.xp);
|
||||
|
||||
tvLeagueName.setText("Liga " + current.name);
|
||||
ivLeagueIcon.setImageResource(current.iconRes);
|
||||
ivLeagueBadgeSmall.setImageResource(current.iconRes);
|
||||
|
||||
if (next != null) {
|
||||
int remaining = next.minXp - user.xp;
|
||||
tvLeagueMotivation.setText("Faltam " + remaining + " XP para " + next.name);
|
||||
} else {
|
||||
tvLeagueMotivation.setText("Estás no topo absoluto!");
|
||||
}
|
||||
}
|
||||
|
||||
private void updateRealStats(Usuario user) {
|
||||
setStatValue(statTotalTasks, String.valueOf(user.total_tasks_concluidas));
|
||||
setStatValue(statBestStreak, String.valueOf(user.melhor_streak));
|
||||
setStatValue(statFocusSessions, String.valueOf(user.sessoes_foco_completas));
|
||||
setStatValue(statTotalFocus, formatTime(user.tempo_foco_total));
|
||||
setStatValue(statDaysCompleted, String.valueOf(user.dias_concluidos != null ? user.dias_concluidos.size() : 0));
|
||||
|
||||
int avg = user.dias_ativos > 0 ? user.tempo_foco_total / user.dias_ativos : 0;
|
||||
setStatValue(statDailyAvg, avg + " min");
|
||||
}
|
||||
|
||||
private void setStatValue(View statView, String value) {
|
||||
if (statView == null) return;
|
||||
((TextView) statView.findViewById(R.id.tvStatIcon)).setText(icon);
|
||||
((TextView) statView.findViewById(R.id.tvStatValue)).setText(value);
|
||||
((TextView) statView.findViewById(R.id.tvStatLabel)).setText(label);
|
||||
}
|
||||
|
||||
private String formatTime(int totalMinutes) {
|
||||
if (totalMinutes < 60) return totalMinutes + "m";
|
||||
int h = totalMinutes / 60;
|
||||
int m = totalMinutes % 60;
|
||||
if (m == 0) return h + "h";
|
||||
return h + "h " + m + "m";
|
||||
}
|
||||
|
||||
private void updateMotivation(Usuario user) {
|
||||
if (user.streak >= 7) {
|
||||
tvConsistencyPhrase.setText("Estás imparável com " + user.streak + " dias seguidos! 🔥");
|
||||
} else if (user.streak > 0) {
|
||||
tvConsistencyPhrase.setText("Continua assim! " + user.streak + " dias de foco.");
|
||||
} else {
|
||||
tvConsistencyPhrase.setText("Começa hoje a tua nova ofensiva! 🚀");
|
||||
}
|
||||
}
|
||||
|
||||
private void updateMiniCalendar(Usuario user) {
|
||||
rvMiniCalendar.setLayoutManager(new LinearLayoutManager(getContext(), LinearLayoutManager.HORIZONTAL, false));
|
||||
|
||||
List<Date> last7Days = new ArrayList<>();
|
||||
Calendar cal = Calendar.getInstance();
|
||||
for (int i = 0; i < 7; i++) {
|
||||
last7Days.add(cal.getTime());
|
||||
cal.add(Calendar.DAY_OF_YEAR, -1);
|
||||
}
|
||||
Collections.reverse(last7Days);
|
||||
|
||||
MiniCalendarAdapter adapter = new MiniCalendarAdapter(last7Days, user.dias_concluidos);
|
||||
rvMiniCalendar.setAdapter(adapter);
|
||||
}
|
||||
|
||||
private void updateWeeklyChart(Usuario user) {
|
||||
weeklyChart.getDescription().setEnabled(false);
|
||||
weeklyChart.setDrawGridBackground(false);
|
||||
weeklyChart.getLegend().setEnabled(false);
|
||||
weeklyChart.setTouchEnabled(false);
|
||||
|
||||
XAxis xAxis = weeklyChart.getXAxis();
|
||||
xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);
|
||||
xAxis.setDrawGridLines(false);
|
||||
xAxis.setTextColor(Color.GRAY);
|
||||
xAxis.setTextSize(10f);
|
||||
|
||||
weeklyChart.getAxisLeft().setDrawGridLines(true);
|
||||
weeklyChart.getAxisLeft().setGridColor(Color.parseColor("#F0F0F0"));
|
||||
weeklyChart.getAxisLeft().setTextColor(Color.GRAY);
|
||||
weeklyChart.getAxisRight().setEnabled(false);
|
||||
|
||||
// Fetch last 7 days of XP logs or use an approximation if logs aren't easily available
|
||||
// For now, let's use a nice mockup using current data if logs are missing
|
||||
List<Entry> entries = new ArrayList<>();
|
||||
String[] days = new String[7];
|
||||
Calendar cal = Calendar.getInstance();
|
||||
cal.add(Calendar.DAY_OF_YEAR, -6);
|
||||
|
||||
SimpleDateFormat sdf = new SimpleDateFormat("E", new Locale("pt", "PT"));
|
||||
|
||||
for (int i = 0; i < 7; i++) {
|
||||
days[i] = sdf.format(cal.getTime()).substring(0, 1).toUpperCase();
|
||||
// Mocking some data based on status if real logs aren't aggregated yet
|
||||
// In a real app, we'd query DailyProgress for the last 7 days
|
||||
float val = (float) (Math.random() * 50 + 20);
|
||||
if (i == 6) val = user.xp_hoje;
|
||||
entries.add(new Entry(i, val));
|
||||
cal.add(Calendar.DAY_OF_YEAR, 1);
|
||||
}
|
||||
|
||||
xAxis.setValueFormatter(new IndexAxisValueFormatter(days));
|
||||
|
||||
LineDataSet set = new LineDataSet(entries, "XP");
|
||||
set.setColor(Color.parseColor("#7C3AED"));
|
||||
set.setLineWidth(3f);
|
||||
set.setCircleColor(Color.parseColor("#7C3AED"));
|
||||
set.setCircleRadius(5f);
|
||||
set.setDrawCircleHole(true);
|
||||
set.setCircleHoleRadius(2f);
|
||||
set.setMode(LineDataSet.Mode.CUBIC_BEZIER);
|
||||
set.setDrawFilled(true);
|
||||
set.setFillDrawable(getResources().getDrawable(R.drawable.chart_fill_gradient));
|
||||
set.setDrawValues(false);
|
||||
|
||||
LineData data = new LineData(set);
|
||||
weeklyChart.setData(data);
|
||||
weeklyChart.animateY(1000);
|
||||
weeklyChart.invalidate();
|
||||
}
|
||||
|
||||
private String determineTitle(Usuario user) {
|
||||
@@ -136,20 +361,37 @@ public class ProfileFragment extends Fragment {
|
||||
LinearLayout badge = new LinearLayout(getContext());
|
||||
badge.setOrientation(LinearLayout.VERTICAL);
|
||||
badge.setGravity(android.view.Gravity.CENTER);
|
||||
badge.setPadding(8, 8, 8, 8);
|
||||
badge.setPadding(4, 12, 4, 12);
|
||||
|
||||
FrameLayout iconFrame = new FrameLayout(getContext());
|
||||
View glow = new View(getContext());
|
||||
int glowSize = (int) (48 * getResources().getDisplayMetrics().density);
|
||||
glow.setLayoutParams(new FrameLayout.LayoutParams(glowSize, glowSize));
|
||||
glow.setBackground(getResources().getDrawable(R.drawable.circle_bg));
|
||||
glow.setBackgroundTintList(android.content.res.ColorStateList.valueOf(Color.parseColor(unlocked ? "#F3E8FF" : "#F3F4F6")));
|
||||
|
||||
TextView tvEmoji = new TextView(getContext());
|
||||
tvEmoji.setText(emoji);
|
||||
tvEmoji.setTextSize(32);
|
||||
tvEmoji.setTextSize(24);
|
||||
FrameLayout.LayoutParams emojiParams = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
|
||||
emojiParams.gravity = android.view.Gravity.CENTER;
|
||||
tvEmoji.setLayoutParams(emojiParams);
|
||||
|
||||
if (!unlocked) tvEmoji.setAlpha(0.3f);
|
||||
|
||||
iconFrame.addView(glow);
|
||||
iconFrame.addView(tvEmoji);
|
||||
|
||||
TextView tvName = new TextView(getContext());
|
||||
tvName.setText(name);
|
||||
tvName.setTextSize(10);
|
||||
tvName.setGravity(android.view.Gravity.CENTER);
|
||||
tvName.setPadding(0, 8, 0, 0);
|
||||
tvName.setTextColor(getResources().getColor(unlocked ? R.color.text_primary : R.color.text_secondary));
|
||||
tvName.setAllCaps(true);
|
||||
tvName.setLetterSpacing(0.05f);
|
||||
|
||||
badge.addView(tvEmoji);
|
||||
badge.addView(iconFrame);
|
||||
badge.addView(tvName);
|
||||
badgesGrid.addView(badge);
|
||||
}
|
||||
@@ -171,11 +413,74 @@ public class ProfileFragment extends Fragment {
|
||||
}
|
||||
|
||||
private void addFriendItem(Usuario friend) {
|
||||
View view = getLayoutInflater().inflate(R.layout.item_ranking_user, friendsListContainer, false);
|
||||
((TextView) view.findViewById(R.id.tvRankingName)).setText(friend.usuario);
|
||||
((TextView) view.findViewById(R.id.tvRankingXP)).setText(friend.xp + " XP");
|
||||
view.findViewById(R.id.ivRankingTrend).setVisibility(View.GONE);
|
||||
friendsListContainer.addView(view);
|
||||
View v = getLayoutInflater().inflate(R.layout.item_ranking_user, friendsListContainer, false);
|
||||
((TextView) v.findViewById(R.id.tvRankingName)).setText(friend.usuario);
|
||||
((TextView) v.findViewById(R.id.tvRankingXP)).setText(friend.xp + " XP");
|
||||
|
||||
// Populate Streak
|
||||
TextView tvStreak = v.findViewById(R.id.tvRankingStreak);
|
||||
if (tvStreak != null) {
|
||||
tvStreak.setText("🔥 " + friend.streak);
|
||||
}
|
||||
|
||||
// Gamify friend item
|
||||
TextView tvRank = v.findViewById(R.id.tvRankPosition);
|
||||
if (tvRank != null) tvRank.setText("#" + (friendsListContainer.getChildCount() + 1));
|
||||
|
||||
friendsListContainer.addView(v);
|
||||
}
|
||||
|
||||
// --- MINI CALENDAR ADAPTER ---
|
||||
private class MiniCalendarAdapter extends RecyclerView.Adapter<MiniCalendarAdapter.ViewHolder> {
|
||||
private List<Date> dates;
|
||||
private List<String> completedDates;
|
||||
private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd", Locale.US);
|
||||
private SimpleDateFormat daySdf = new SimpleDateFormat("E", new Locale("pt", "PT"));
|
||||
|
||||
public MiniCalendarAdapter(List<Date> dates, List<String> completedDates) {
|
||||
this.dates = dates;
|
||||
this.completedDates = completedDates != null ? completedDates : new ArrayList<>();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_mini_calendar_day, parent, false);
|
||||
return new ViewHolder(v);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
|
||||
Date date = dates.get(position);
|
||||
String dateStr = sdf.format(date);
|
||||
String todayStr = sdf.format(new Date());
|
||||
|
||||
holder.tvDayName.setText(daySdf.format(date).substring(0, 1).toUpperCase());
|
||||
|
||||
if (completedDates.contains(dateStr)) {
|
||||
holder.vDayIndicator.setBackgroundTintList(android.content.res.ColorStateList.valueOf(Color.parseColor("#22C55E")));
|
||||
} else if (dateStr.equals(todayStr)) {
|
||||
holder.vDayIndicator.setBackgroundTintList(android.content.res.ColorStateList.valueOf(Color.parseColor("#7C3AED")));
|
||||
} else {
|
||||
holder.vDayIndicator.setBackgroundTintList(android.content.res.ColorStateList.valueOf(Color.parseColor("#E5E7EB")));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return dates.size();
|
||||
}
|
||||
|
||||
class ViewHolder extends RecyclerView.ViewHolder {
|
||||
TextView tvDayName;
|
||||
View vDayIndicator;
|
||||
|
||||
public ViewHolder(@NonNull View itemView) {
|
||||
super(itemView);
|
||||
tvDayName = itemView.findViewById(R.id.tvDayName);
|
||||
vDayIndicator = itemView.findViewById(R.id.vDayIndicator);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -9,49 +9,66 @@
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
android:orientation="vertical"
|
||||
android:paddingBottom="40dp">
|
||||
|
||||
<!-- 👤 HEADER DO PERFIL -->
|
||||
<RelativeLayout
|
||||
<!-- 👤 HEADER MODERNIZADO -->
|
||||
<FrameLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/primary_purple"
|
||||
android:paddingTop="32dp"
|
||||
android:paddingBottom="24dp"
|
||||
android:paddingHorizontal="20dp"
|
||||
android:clipToPadding="false">
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/btnEditProfile"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="40dp"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_alignParentTop="true"
|
||||
android:background="?attr/selectableItemBackgroundBorderless"
|
||||
android:src="@drawable/ic_settings"
|
||||
app:tint="@color/white" />
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="220dp"
|
||||
android:background="@color/primary_purple" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="16dp"
|
||||
android:gravity="center"
|
||||
android:orientation="vertical">
|
||||
android:orientation="vertical"
|
||||
android:paddingTop="48dp"
|
||||
android:paddingHorizontal="24dp"
|
||||
android:gravity="center">
|
||||
|
||||
<androidx.cardview.widget.CardView
|
||||
android:id="@+id/cardAvatar"
|
||||
android:layout_width="100dp"
|
||||
android:layout_height="100dp"
|
||||
app:cardCornerRadius="50dp"
|
||||
app:cardElevation="4dp"
|
||||
<RelativeLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="12dp">
|
||||
|
||||
<!-- GLOW EFFECT -->
|
||||
<View
|
||||
android:layout_width="120dp"
|
||||
android:layout_height="120dp"
|
||||
android:layout_centerInParent="true"
|
||||
android:background="@drawable/circle_bg"
|
||||
android:backgroundTint="#40FFFFFF" />
|
||||
|
||||
<androidx.cardview.widget.CardView
|
||||
android:id="@+id/cardAvatar"
|
||||
android:layout_width="110dp"
|
||||
android:layout_height="110dp"
|
||||
android:layout_centerInParent="true"
|
||||
app:cardCornerRadius="55dp"
|
||||
app:cardElevation="8dp">
|
||||
<ImageView
|
||||
android:id="@+id/ivProfileAvatar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:scaleType="centerCrop"
|
||||
android:src="@drawable/ic_nav_profile" />
|
||||
</androidx.cardview.widget.CardView>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/ivProfileAvatar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:scaleType="centerCrop"
|
||||
android:src="@drawable/ic_nav_profile" />
|
||||
</androidx.cardview.widget.CardView>
|
||||
android:id="@+id/ivLeagueBadgeSmall"
|
||||
android:layout_width="44dp"
|
||||
android:layout_height="44dp"
|
||||
android:layout_alignBottom="@id/cardAvatar"
|
||||
android:layout_alignEnd="@id/cardAvatar"
|
||||
android:layout_marginEnd="-6dp"
|
||||
android:layout_marginBottom="-6dp"
|
||||
android:elevation="12dp"
|
||||
android:src="@drawable/ic_trophy_bronze" />
|
||||
</RelativeLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvProfileName"
|
||||
@@ -59,7 +76,7 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Carregando..."
|
||||
android:textColor="@color/white"
|
||||
android:textSize="24sp"
|
||||
android:textSize="26sp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<TextView
|
||||
@@ -68,191 +85,249 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@username"
|
||||
android:textColor="#E0E0E0"
|
||||
android:textSize="14sp"
|
||||
android:layout_marginTop="2dp"/>
|
||||
android:textSize="14sp" />
|
||||
|
||||
<!-- 🔥 NÍVEL E XP BAR -->
|
||||
<androidx.cardview.widget.CardView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="20dp"
|
||||
app:cardCornerRadius="20dp"
|
||||
app:cardElevation="4dp">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvProfileSince"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Aqui desde 2024"
|
||||
android:textColor="#C0C0C0"
|
||||
android:textSize="12sp"
|
||||
android:layout_marginTop="4dp"/>
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:padding="16dp">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvProfileBio"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Sem bio definida."
|
||||
android:textColor="#E0E0E0"
|
||||
android:textSize="14sp"
|
||||
android:gravity="center"
|
||||
android:layout_marginTop="8dp" />
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="8dp">
|
||||
<TextView
|
||||
android:id="@+id/tvUserLevel"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Nível 7"
|
||||
android:textStyle="bold"
|
||||
android:textColor="@color/text_primary"
|
||||
android:textSize="16sp"/>
|
||||
<TextView
|
||||
android:id="@+id/tvXpFraction"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:text="1010 / 1500 XP"
|
||||
android:textColor="@color/text_secondary"
|
||||
android:textSize="13sp"/>
|
||||
</RelativeLayout>
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/pbXpLevel"
|
||||
style="?android:attr/progressBarStyleHorizontal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="12dp"
|
||||
android:progress="60"
|
||||
android:progressDrawable="@drawable/xp_progress_bar" />
|
||||
</LinearLayout>
|
||||
</androidx.cardview.widget.CardView>
|
||||
</LinearLayout>
|
||||
</RelativeLayout>
|
||||
|
||||
<!-- MAIN CONTENT AREA -->
|
||||
<ImageButton
|
||||
android:id="@+id/btnEditProfile"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="48dp"
|
||||
android:layout_gravity="end|top"
|
||||
android:layout_marginTop="40dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:background="?attr/selectableItemBackgroundBorderless"
|
||||
android:src="@drawable/ic_settings"
|
||||
app:tint="@color/white" />
|
||||
</FrameLayout>
|
||||
|
||||
<!-- CONTENT -->
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:padding="20dp">
|
||||
android:paddingHorizontal="20dp"
|
||||
android:paddingTop="24dp">
|
||||
|
||||
<!-- 📊 ESTATÍSTICAS PRINCIPAIS (Em linha) -->
|
||||
<LinearLayout
|
||||
<!-- 🏆 LIGA ATUAL -->
|
||||
<androidx.cardview.widget.CardView
|
||||
android:id="@+id/cardLeague"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:weightSum="4"
|
||||
android:layout_marginBottom="24dp">
|
||||
|
||||
android:layout_marginBottom="24dp"
|
||||
app:cardCornerRadius="16dp"
|
||||
app:cardElevation="2dp">
|
||||
<LinearLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:orientation="vertical"
|
||||
android:gravity="center">
|
||||
<TextView
|
||||
android:id="@+id/tvStatTopXP"
|
||||
android:layout_width="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:padding="16dp"
|
||||
android:gravity="center_vertical">
|
||||
<ImageView
|
||||
android:id="@+id/ivLeagueIcon"
|
||||
android:layout_width="60dp"
|
||||
android:layout_height="60dp"
|
||||
android:src="@drawable/ic_trophy_bronze" />
|
||||
<LinearLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="0"
|
||||
android:textStyle="bold"
|
||||
android:textSize="18sp"
|
||||
android:textColor="@color/text_primary"/>
|
||||
android:layout_weight="1"
|
||||
android:layout_marginStart="16dp"
|
||||
android:orientation="vertical">
|
||||
<TextView
|
||||
android:id="@+id/tvLeagueName"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Liga Bronze"
|
||||
android:textStyle="bold"
|
||||
android:textSize="18sp"
|
||||
android:textColor="@color/text_primary"/>
|
||||
<TextView
|
||||
android:id="@+id/tvLeagueMotivation"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Faltam 490 XP para Prata"
|
||||
android:textColor="@color/text_secondary"
|
||||
android:textSize="13sp"/>
|
||||
</LinearLayout>
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="XP"
|
||||
android:textSize="12sp"
|
||||
android:textColor="@color/text_secondary"/>
|
||||
android:text=">"
|
||||
android:textColor="@color/text_secondary"
|
||||
android:textSize="20sp" />
|
||||
</LinearLayout>
|
||||
</androidx.cardview.widget.CardView>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:orientation="vertical"
|
||||
android:gravity="center">
|
||||
<TextView
|
||||
android:id="@+id/tvStatFollowing"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="0"
|
||||
android:textStyle="bold"
|
||||
android:textSize="18sp"
|
||||
android:textColor="@color/text_primary"/>
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="A seguir"
|
||||
android:textSize="12sp"
|
||||
android:textColor="@color/text_secondary"/>
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:orientation="vertical"
|
||||
android:gravity="center">
|
||||
<TextView
|
||||
android:id="@+id/tvStatFollowers"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="0"
|
||||
android:textStyle="bold"
|
||||
android:textSize="18sp"
|
||||
android:textColor="@color/text_primary"/>
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Seguidores"
|
||||
android:textSize="12sp"
|
||||
android:textColor="@color/text_secondary"/>
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:orientation="vertical"
|
||||
android:gravity="center">
|
||||
<TextView
|
||||
android:id="@+id/tvStatActiveDays"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="0"
|
||||
android:textStyle="bold"
|
||||
android:textSize="18sp"
|
||||
android:textColor="@color/text_primary"/>
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Dias ativos"
|
||||
android:textSize="12sp"
|
||||
android:textColor="@color/text_secondary"/>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<!-- MAIN BUTTON -->
|
||||
<Button
|
||||
android:id="@+id/btnAddFriends"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="56dp"
|
||||
android:text="Adicionar Amigos"
|
||||
android:backgroundTint="@color/primary_purple"
|
||||
android:textColor="@color/white"
|
||||
<!-- 📅 MINI CALENDÁRIO -->
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="CONSISTÊNCIA"
|
||||
android:textStyle="bold"
|
||||
app:cornerRadius="12dp"
|
||||
android:layout_marginBottom="32dp"/>
|
||||
android:textSize="14sp"
|
||||
android:textColor="@color/text_secondary"
|
||||
android:layout_marginBottom="12dp"
|
||||
android:letterSpacing="0.1" />
|
||||
|
||||
<!-- VISÃO GERAL -->
|
||||
<androidx.cardview.widget.CardView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="24dp"
|
||||
app:cardCornerRadius="16dp"
|
||||
app:cardElevation="1dp">
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:padding="16dp">
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/rvMiniCalendar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvConsistencyPhrase"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="12dp"
|
||||
android:text="Estás imparável este mês! 🔥"
|
||||
android:textColor="@color/primary_purple"
|
||||
android:textStyle="italic"
|
||||
android:textSize="13sp"
|
||||
android:gravity="center"/>
|
||||
</LinearLayout>
|
||||
</androidx.cardview.widget.CardView>
|
||||
|
||||
<!-- 📊 VISÃO GERAL (STATS REAIS) -->
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="VISÃO GERAL"
|
||||
android:textStyle="bold"
|
||||
android:textSize="16sp"
|
||||
android:textSize="14sp"
|
||||
android:textColor="@color/text_secondary"
|
||||
android:layout_marginBottom="12dp" />
|
||||
android:layout_marginBottom="12dp"
|
||||
android:letterSpacing="0.1" />
|
||||
|
||||
<HorizontalScrollView
|
||||
<GridLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:scrollbars="none"
|
||||
android:layout_marginBottom="32dp">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:columnCount="2"
|
||||
android:rowCount="3"
|
||||
android:layout_marginBottom="24dp"
|
||||
android:alignmentMode="alignMargins"
|
||||
android:columnOrderPreserved="false">
|
||||
|
||||
<include layout="@layout/item_profile_stat_modern"
|
||||
android:id="@+id/statTotalTasks"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:paddingEnd="20dp">
|
||||
android:layout_columnWeight="1"
|
||||
android:layout_margin="4dp"/>
|
||||
<include layout="@layout/item_profile_stat_modern"
|
||||
android:id="@+id/statBestStreak"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_columnWeight="1"
|
||||
android:layout_margin="4dp"/>
|
||||
<include layout="@layout/item_profile_stat_modern"
|
||||
android:id="@+id/statFocusSessions"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_columnWeight="1"
|
||||
android:layout_margin="4dp"/>
|
||||
<include layout="@layout/item_profile_stat_modern"
|
||||
android:id="@+id/statTotalFocus"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_columnWeight="1"
|
||||
android:layout_margin="4dp"/>
|
||||
<include layout="@layout/item_profile_stat_modern"
|
||||
android:id="@+id/statDaysCompleted"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_columnWeight="1"
|
||||
android:layout_margin="4dp"/>
|
||||
<include layout="@layout/item_profile_stat_modern"
|
||||
android:id="@+id/statDailyAvg"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_columnWeight="1"
|
||||
android:layout_margin="4dp"/>
|
||||
</GridLayout>
|
||||
|
||||
<include layout="@layout/item_stat_small"
|
||||
android:id="@+id/statStreak"
|
||||
android:layout_width="100dp"
|
||||
android:layout_height="wrap_content" />
|
||||
<!-- 📈 GRÁFICO SEMANAL -->
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="PROGRESSO SEMANAL"
|
||||
android:textStyle="bold"
|
||||
android:textSize="14sp"
|
||||
android:textColor="@color/text_secondary"
|
||||
android:layout_marginBottom="12dp"
|
||||
android:letterSpacing="0.1" />
|
||||
|
||||
<include layout="@layout/item_stat_small"
|
||||
android:id="@+id/statLeague"
|
||||
android:layout_width="100dp"
|
||||
android:layout_height="wrap_content" />
|
||||
<androidx.cardview.widget.CardView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="200dp"
|
||||
android:layout_marginBottom="24dp"
|
||||
app:cardCornerRadius="16dp"
|
||||
app:cardElevation="1dp">
|
||||
<com.github.mikephil.charting.charts.LineChart
|
||||
android:id="@+id/weeklyChart"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:padding="8dp"/>
|
||||
</androidx.cardview.widget.CardView>
|
||||
|
||||
<include layout="@layout/item_stat_small"
|
||||
android:id="@+id/statXP"
|
||||
android:layout_width="100dp"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<include layout="@layout/item_stat_small"
|
||||
android:id="@+id/statFocusTime"
|
||||
android:layout_width="100dp"
|
||||
android:layout_height="wrap_content" />
|
||||
</LinearLayout>
|
||||
</HorizontalScrollView>
|
||||
|
||||
<!-- 👥 AMIGOS -->
|
||||
<!-- 🎖 CONQUISTAS -->
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
@@ -260,84 +335,28 @@
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="AMIGOS"
|
||||
android:text="CONQUISTAS"
|
||||
android:textStyle="bold"
|
||||
android:textSize="16sp"
|
||||
android:textSize="14sp"
|
||||
android:textColor="@color/text_secondary"
|
||||
android:layout_centerVertical="true"/>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center_vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/btnViewAllFriends"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="VER TODOS"
|
||||
android:textColor="@color/primary_purple"
|
||||
android:textStyle="bold"
|
||||
android:textSize="12sp"
|
||||
android:padding="8dp"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/btnFindFriends"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="+"
|
||||
android:textColor="@color/primary_purple"
|
||||
android:textSize="24sp"
|
||||
android:textStyle="bold"
|
||||
android:padding="8dp"
|
||||
android:layout_marginStart="8dp"
|
||||
android:background="?attr/selectableItemBackgroundBorderless" />
|
||||
</LinearLayout>
|
||||
</RelativeLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/friendsListContainer"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:layout_marginBottom="32dp"/>
|
||||
|
||||
<!-- 🏆 MEDALHAS -->
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="12dp">
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="MEDALHAS"
|
||||
android:textStyle="bold"
|
||||
android:textSize="16sp"
|
||||
android:textColor="@color/text_secondary"
|
||||
android:layout_centerVertical="true"/>
|
||||
|
||||
android:letterSpacing="0.1" />
|
||||
<TextView
|
||||
android:id="@+id/btnViewAllBadges"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:text=">"
|
||||
android:textColor="@color/text_secondary"
|
||||
android:textSize="20sp"
|
||||
android:text="VER TODAS"
|
||||
android:textColor="@color/primary_purple"
|
||||
android:textStyle="bold"
|
||||
android:padding="8dp"
|
||||
android:background="?attr/selectableItemBackgroundBorderless" />
|
||||
android:textSize="12sp"/>
|
||||
</RelativeLayout>
|
||||
|
||||
<androidx.cardview.widget.CardView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="32dp"
|
||||
android:layout_marginBottom="24dp"
|
||||
app:cardCornerRadius="16dp"
|
||||
app:cardElevation="1dp"
|
||||
app:cardBackgroundColor="@color/white">
|
||||
app:cardElevation="1dp">
|
||||
<GridLayout
|
||||
android:id="@+id/badgesGrid"
|
||||
android:layout_width="match_parent"
|
||||
@@ -345,11 +364,72 @@
|
||||
android:columnCount="4"
|
||||
android:padding="16dp"
|
||||
android:gravity="center">
|
||||
<!-- Badges will be added here -->
|
||||
</GridLayout>
|
||||
</androidx.cardview.widget.CardView>
|
||||
|
||||
<!-- 🔘 BOTÕES DE ACÇÃO -->
|
||||
<!-- 👥 AMIGOS -->
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="12dp">
|
||||
<TextView
|
||||
android:id="@+id/titleAmigos"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="AMIGOS"
|
||||
android:textStyle="bold"
|
||||
android:textSize="14sp"
|
||||
android:textColor="@color/text_secondary"
|
||||
android:letterSpacing="0.1" />
|
||||
|
||||
<!-- BOTÃO "+" (btnAddFriends) -->
|
||||
<TextView
|
||||
android:id="@+id/btnAddFriends"
|
||||
android:layout_width="32dp"
|
||||
android:layout_height="32dp"
|
||||
android:layout_toEndOf="@id/titleAmigos"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginTop="-6dp"
|
||||
android:text="+"
|
||||
android:gravity="center"
|
||||
android:textColor="@color/primary_purple"
|
||||
android:textStyle="bold"
|
||||
android:textSize="22sp"
|
||||
android:background="?attr/selectableItemBackgroundBorderless"
|
||||
android:clickable="true"
|
||||
android:focusable="true"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/btnViewAllFriends"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:text="VER TODOS"
|
||||
android:textColor="@color/primary_purple"
|
||||
android:textStyle="bold"
|
||||
android:textSize="12sp"/>
|
||||
</RelativeLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/friendsListContainer"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:layout_marginBottom="8dp"/>
|
||||
|
||||
<!-- BOTÃO "ADICIONAR AMIGOS" (btnFindFriends) -->
|
||||
<Button
|
||||
android:id="@+id/btnFindFriends"
|
||||
style="@style/Widget.MaterialComponents.Button.TextButton"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="32dp"
|
||||
android:text="ADICIONAR AMIGOS"
|
||||
android:textColor="@color/primary_purple"
|
||||
android:textStyle="bold"
|
||||
app:rippleColor="#207C3AED" />
|
||||
|
||||
<!-- 🔘 LOGOUT -->
|
||||
<Button
|
||||
android:id="@+id/btnLogout"
|
||||
android:layout_width="match_parent"
|
||||
@@ -359,10 +439,8 @@
|
||||
android:textColor="@color/error_red"
|
||||
app:strokeColor="@color/error_red"
|
||||
app:strokeWidth="1dp"
|
||||
app:cornerRadius="12dp"
|
||||
android:layout_marginBottom="40dp"/>
|
||||
app:cornerRadius="12dp" />
|
||||
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
</androidx.core.widget.NestedScrollView>
|
||||
|
||||
|
||||
@@ -55,15 +55,30 @@
|
||||
android:textSize="14sp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvRankingLabelTu"
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Tu"
|
||||
android:textColor="@color/primary_purple"
|
||||
android:textSize="10sp"
|
||||
android:textStyle="bold"
|
||||
android:visibility="gone" />
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center_vertical">
|
||||
<TextView
|
||||
android:id="@+id/tvRankingStreak"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="🔥 7"
|
||||
android:textColor="@color/streak_orange"
|
||||
android:textSize="11sp"
|
||||
android:textStyle="bold"
|
||||
android:layout_marginEnd="8dp"/>
|
||||
<TextView
|
||||
android:id="@+id/tvRankingLabelTu"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Tu"
|
||||
android:textColor="@color/primary_purple"
|
||||
android:textSize="10sp"
|
||||
android:textStyle="bold"
|
||||
android:visibility="gone" />
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
@@ -81,6 +96,7 @@
|
||||
android:layout_height="16dp"
|
||||
android:layout_marginStart="8dp"
|
||||
android:src="@drawable/ic_trend_up"
|
||||
android:visibility="gone"
|
||||
app:tint="@color/success_green" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
Reference in New Issue
Block a user