grafico
This commit is contained in:
12
.idea/caches/deviceStreaming.xml
generated
12
.idea/caches/deviceStreaming.xml
generated
@@ -1464,6 +1464,18 @@
|
|||||||
<option name="screenX" value="1856" />
|
<option name="screenX" value="1856" />
|
||||||
<option name="screenY" value="2160" />
|
<option name="screenY" value="2160" />
|
||||||
</PersistentDeviceSelectionData>
|
</PersistentDeviceSelectionData>
|
||||||
|
<PersistentDeviceSelectionData>
|
||||||
|
<option name="api" value="36" />
|
||||||
|
<option name="brand" value="samsung" />
|
||||||
|
<option name="codename" value="q7mq" />
|
||||||
|
<option name="id" value="q7mq" />
|
||||||
|
<option name="labId" value="google" />
|
||||||
|
<option name="manufacturer" value="Samsung" />
|
||||||
|
<option name="name" value="Galaxy Z TriFold" />
|
||||||
|
<option name="screenDensity" value="320" />
|
||||||
|
<option name="screenX" value="2160" />
|
||||||
|
<option name="screenY" value="1584" />
|
||||||
|
</PersistentDeviceSelectionData>
|
||||||
<PersistentDeviceSelectionData>
|
<PersistentDeviceSelectionData>
|
||||||
<option name="api" value="36" />
|
<option name="api" value="36" />
|
||||||
<option name="brand" value="samsung" />
|
<option name="brand" value="samsung" />
|
||||||
|
|||||||
@@ -1,56 +1,333 @@
|
|||||||
|
|
||||||
package com.fluxup.app;
|
package com.fluxup.app;
|
||||||
|
|
||||||
|
import android.graphics.Color;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.text.Editable;
|
import android.text.Editable;
|
||||||
import android.text.TextWatcher;
|
import android.text.TextWatcher;
|
||||||
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.ArrayAdapter;
|
|
||||||
import android.widget.EditText;
|
import android.widget.EditText;
|
||||||
|
import android.widget.ImageView;
|
||||||
|
import android.widget.TextView;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.fragment.app.Fragment;
|
import androidx.fragment.app.Fragment;
|
||||||
import android.widget.ListView;
|
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||||
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
|
import com.github.mikephil.charting.charts.BarChart;
|
||||||
|
import com.github.mikephil.charting.components.XAxis;
|
||||||
|
import com.github.mikephil.charting.data.BarData;
|
||||||
|
import com.github.mikephil.charting.data.BarDataSet;
|
||||||
|
import com.github.mikephil.charting.data.BarEntry;
|
||||||
|
import com.github.mikephil.charting.formatter.ValueFormatter;
|
||||||
|
import com.google.firebase.auth.FirebaseAuth;
|
||||||
|
import com.google.firebase.firestore.FirebaseFirestore;
|
||||||
|
import com.google.firebase.firestore.Query;
|
||||||
|
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Calendar;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
public class SearchFragment extends Fragment {
|
public class SearchFragment extends Fragment {
|
||||||
|
|
||||||
private ListView recyclerView;
|
|
||||||
private EditText searchBar;
|
private EditText searchBar;
|
||||||
private ArrayAdapter<String> adapter;
|
private BarChart weeklyChart;
|
||||||
private ArrayList<String> allItems;
|
private TextView tvEmptyState;
|
||||||
|
private RecyclerView rvChallenges, rvFeaturedUsers;
|
||||||
|
private ChallengeAdapter challengeAdapter;
|
||||||
|
private FeaturedUserAdapter userAdapter;
|
||||||
|
|
||||||
|
private final FirestoreManager firestoreManager = FirestoreManager.getInstance();
|
||||||
|
private final String currentUserId = FirebaseAuth.getInstance().getUid();
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
||||||
View view = inflater.inflate(R.layout.fragment_search, container, false);
|
View view = inflater.inflate(R.layout.fragment_search, container, false);
|
||||||
|
|
||||||
recyclerView = view.findViewById(R.id.recycler_view);
|
initViews(view);
|
||||||
searchBar = view.findViewById(R.id.search_bar);
|
setupCharts();
|
||||||
|
setupRecyclerViews();
|
||||||
allItems = new ArrayList<>(Arrays.asList("Item 1", "Item 2", "Item 3", "Another Item", "More Items"));
|
loadData();
|
||||||
|
setupSearch();
|
||||||
adapter = new ArrayAdapter<>(getContext(), android.R.layout.simple_list_item_1, allItems);
|
|
||||||
recyclerView.setAdapter(adapter);
|
|
||||||
|
|
||||||
searchBar.addTextChangedListener(new TextWatcher() {
|
|
||||||
@Override
|
|
||||||
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
|
||||||
adapter.getFilter().filter(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void afterTextChanged(Editable s) {
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return view;
|
return view;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void initViews(View view) {
|
||||||
|
searchBar = view.findViewById(R.id.search_bar);
|
||||||
|
weeklyChart = view.findViewById(R.id.weeklyChart);
|
||||||
|
tvEmptyState = view.findViewById(R.id.tvEmptyState);
|
||||||
|
rvChallenges = view.findViewById(R.id.rvChallenges);
|
||||||
|
rvFeaturedUsers = view.findViewById(R.id.rvFeaturedUsers);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setupCharts() {
|
||||||
|
weeklyChart.getDescription().setEnabled(false);
|
||||||
|
weeklyChart.getLegend().setEnabled(false);
|
||||||
|
weeklyChart.setDrawGridBackground(false);
|
||||||
|
weeklyChart.setDrawBarShadow(false);
|
||||||
|
weeklyChart.setDrawValueAboveBar(true);
|
||||||
|
weeklyChart.setTouchEnabled(false);
|
||||||
|
|
||||||
|
XAxis xAxis = weeklyChart.getXAxis();
|
||||||
|
xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);
|
||||||
|
xAxis.setDrawGridLines(false);
|
||||||
|
xAxis.setGranularity(1f);
|
||||||
|
xAxis.setTextColor(Color.parseColor("#94A3B8"));
|
||||||
|
|
||||||
|
String[] days = {"SEG", "TER", "QUA", "QUI", "SEX", "SAB", "DOM"};
|
||||||
|
xAxis.setValueFormatter(new ValueFormatter() {
|
||||||
|
@Override
|
||||||
|
public String getFormattedValue(float value) {
|
||||||
|
int index = (int) value;
|
||||||
|
if (index >= 0 && index < days.length) return days[index];
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
weeklyChart.getAxisLeft().setDrawGridLines(true);
|
||||||
|
weeklyChart.getAxisLeft().setGridColor(Color.parseColor("#E2E8F0"));
|
||||||
|
weeklyChart.getAxisLeft().setTextColor(Color.parseColor("#94A3B8"));
|
||||||
|
weeklyChart.getAxisRight().setEnabled(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setupRecyclerViews() {
|
||||||
|
// Challenges
|
||||||
|
rvChallenges.setLayoutManager(new LinearLayoutManager(getContext(), LinearLayoutManager.HORIZONTAL, false));
|
||||||
|
challengeAdapter = new ChallengeAdapter(getMockChallenges());
|
||||||
|
rvChallenges.setAdapter(challengeAdapter);
|
||||||
|
|
||||||
|
// Featured Users
|
||||||
|
rvFeaturedUsers.setLayoutManager(new LinearLayoutManager(getContext()));
|
||||||
|
userAdapter = new FeaturedUserAdapter(new ArrayList<>());
|
||||||
|
rvFeaturedUsers.setAdapter(userAdapter);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setupSearch() {
|
||||||
|
searchBar.addTextChangedListener(new TextWatcher() {
|
||||||
|
@Override
|
||||||
|
public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||||
|
filterUsers(s.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterTextChanged(Editable s) {}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loadData() {
|
||||||
|
if (currentUserId == null) return;
|
||||||
|
|
||||||
|
// Load Weekly Progress
|
||||||
|
Calendar cal = Calendar.getInstance();
|
||||||
|
cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
|
||||||
|
cal.set(Calendar.HOUR_OF_DAY, 0);
|
||||||
|
cal.set(Calendar.MINUTE, 0);
|
||||||
|
cal.set(Calendar.SECOND, 0);
|
||||||
|
Date startDate = cal.getTime();
|
||||||
|
|
||||||
|
cal.add(Calendar.DAY_OF_WEEK, 6);
|
||||||
|
cal.set(Calendar.HOUR_OF_DAY, 23);
|
||||||
|
cal.set(Calendar.MINUTE, 59);
|
||||||
|
cal.set(Calendar.SECOND, 59);
|
||||||
|
Date endDate = cal.getTime();
|
||||||
|
|
||||||
|
firestoreManager.getDailyProgress(currentUserId, startDate, endDate, 3, progressMap -> {
|
||||||
|
updateChart(progressMap);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Load Featured Users (mocking top users from Firestore)
|
||||||
|
FirebaseFirestore.getInstance().collection("users")
|
||||||
|
.orderBy("xp", Query.Direction.DESCENDING)
|
||||||
|
.limit(10)
|
||||||
|
.get()
|
||||||
|
.addOnSuccessListener(snapshots -> {
|
||||||
|
List<Usuario> users = new ArrayList<>();
|
||||||
|
for (com.google.firebase.firestore.DocumentSnapshot doc : snapshots) {
|
||||||
|
Usuario u = doc.toObject(Usuario.class);
|
||||||
|
if (u != null) users.add(u);
|
||||||
|
}
|
||||||
|
userAdapter.updateList(users);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateChart(Map<String, DailyProgress> progressMap) {
|
||||||
|
if (progressMap.isEmpty()) {
|
||||||
|
weeklyChart.setVisibility(View.GONE);
|
||||||
|
tvEmptyState.setVisibility(View.VISIBLE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
weeklyChart.setVisibility(View.VISIBLE);
|
||||||
|
tvEmptyState.setVisibility(View.GONE);
|
||||||
|
|
||||||
|
List<BarEntry> entries = new ArrayList<>();
|
||||||
|
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd", Locale.US);
|
||||||
|
Calendar cal = Calendar.getInstance();
|
||||||
|
cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
|
||||||
|
|
||||||
|
int todayIndex = Calendar.getInstance().get(Calendar.DAY_OF_WEEK) - 2;
|
||||||
|
if (todayIndex < 0) todayIndex = 6; // Sunday fix
|
||||||
|
|
||||||
|
List<Integer> colors = new ArrayList<>();
|
||||||
|
|
||||||
|
for (int i = 0; i < 7; i++) {
|
||||||
|
String dateStr = sdf.format(cal.getTime());
|
||||||
|
DailyProgress dp = progressMap.get(dateStr);
|
||||||
|
int xp = (dp != null) ? dp.xp : 0;
|
||||||
|
entries.add(new BarEntry(i, xp));
|
||||||
|
|
||||||
|
if (i == todayIndex) {
|
||||||
|
colors.add(Color.parseColor("#7C3AED")); // Roxo principal destaque
|
||||||
|
} else {
|
||||||
|
colors.add(Color.parseColor("#DDD6FE")); // Roxo claro
|
||||||
|
}
|
||||||
|
cal.add(Calendar.DAY_OF_WEEK, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
BarDataSet dataSet = new BarDataSet(entries, "XP");
|
||||||
|
dataSet.setColors(colors);
|
||||||
|
dataSet.setDrawValues(true);
|
||||||
|
dataSet.setValueTextColor(Color.parseColor("#7C3AED"));
|
||||||
|
dataSet.setValueTextSize(10f);
|
||||||
|
|
||||||
|
BarData data = new BarData(dataSet);
|
||||||
|
data.setBarWidth(0.6f);
|
||||||
|
|
||||||
|
weeklyChart.setData(data);
|
||||||
|
weeklyChart.animateY(1000);
|
||||||
|
weeklyChart.invalidate();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void filterUsers(String query) {
|
||||||
|
userAdapter.filter(query);
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<Challenge> getMockChallenges() {
|
||||||
|
List<Challenge> list = new ArrayList<>();
|
||||||
|
list.add(new Challenge("🎯", "7 dias sem procrastinar", 500));
|
||||||
|
list.add(new Challenge("📚", "Ler 20 min por dia", 300));
|
||||||
|
list.add(new Challenge("⏱️", "30 min foco diário", 400));
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- ADAPTERS ---
|
||||||
|
|
||||||
|
private static class Challenge {
|
||||||
|
String icon, name;
|
||||||
|
int xp;
|
||||||
|
Challenge(String icon, String name, int xp) {
|
||||||
|
this.icon = icon; this.name = name; this.xp = xp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class ChallengeAdapter extends RecyclerView.Adapter<ChallengeAdapter.ViewHolder> {
|
||||||
|
private final List<Challenge> items;
|
||||||
|
ChallengeAdapter(List<Challenge> items) { this.items = items; }
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
@Override
|
||||||
|
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||||
|
return new ViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_challenge, parent, false));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
|
||||||
|
Challenge item = items.get(position);
|
||||||
|
holder.icon.setText(item.icon);
|
||||||
|
holder.name.setText(item.name);
|
||||||
|
holder.xp.setText("+" + item.xp + " XP");
|
||||||
|
holder.btn.setOnClickListener(v -> Toast.makeText(getContext(), "Desafio iniciado!", Toast.LENGTH_SHORT).show());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getItemCount() { return items.size(); }
|
||||||
|
|
||||||
|
class ViewHolder extends RecyclerView.ViewHolder {
|
||||||
|
TextView icon, name, xp;
|
||||||
|
View btn;
|
||||||
|
ViewHolder(View v) {
|
||||||
|
super(v);
|
||||||
|
icon = v.findViewById(R.id.tvChallengeIcon);
|
||||||
|
name = v.findViewById(R.id.tvChallengeName);
|
||||||
|
xp = v.findViewById(R.id.tvChallengeXP);
|
||||||
|
btn = v.findViewById(R.id.btnStartChallenge);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class FeaturedUserAdapter extends RecyclerView.Adapter<FeaturedUserAdapter.ViewHolder> {
|
||||||
|
private List<Usuario> items;
|
||||||
|
private List<Usuario> fullList;
|
||||||
|
|
||||||
|
FeaturedUserAdapter(List<Usuario> items) {
|
||||||
|
this.items = items;
|
||||||
|
this.fullList = new ArrayList<>(items);
|
||||||
|
}
|
||||||
|
|
||||||
|
void updateList(List<Usuario> newList) {
|
||||||
|
this.items = newList;
|
||||||
|
this.fullList = new ArrayList<>(newList);
|
||||||
|
notifyDataSetChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
void filter(String query) {
|
||||||
|
if (query.isEmpty()) {
|
||||||
|
items = new ArrayList<>(fullList);
|
||||||
|
} else {
|
||||||
|
items = new ArrayList<>();
|
||||||
|
for (Usuario u : fullList) {
|
||||||
|
if (u.usuario.toLowerCase().contains(query.toLowerCase())) {
|
||||||
|
items.add(u);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
notifyDataSetChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
@Override
|
||||||
|
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||||
|
return new ViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_featured_user, parent, false));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
|
||||||
|
Usuario user = items.get(position);
|
||||||
|
holder.name.setText(user.usuario);
|
||||||
|
holder.stats.setText("🔥 " + user.streak + " dias • " + user.league);
|
||||||
|
// holder.avatar setup if needed
|
||||||
|
holder.btnAdd.setOnClickListener(v -> Toast.makeText(getContext(), "Pedido enviado!", Toast.LENGTH_SHORT).show());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getItemCount() { return items.size(); }
|
||||||
|
|
||||||
|
class ViewHolder extends RecyclerView.ViewHolder {
|
||||||
|
ImageView avatar;
|
||||||
|
TextView name, stats;
|
||||||
|
View btnAdd;
|
||||||
|
ViewHolder(View v) {
|
||||||
|
super(v);
|
||||||
|
avatar = v.findViewById(R.id.ivUserAvatar);
|
||||||
|
name = v.findViewById(R.id.tvUserName);
|
||||||
|
stats = v.findViewById(R.id.tvUserStats);
|
||||||
|
btnAdd = v.findViewById(R.id.btnAddFriend);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,18 +1,151 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<androidx.core.widget.NestedScrollView 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_width="match_parent"
|
||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent"
|
||||||
|
android:background="@color/background_light"
|
||||||
|
android:fillViewport="true">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:paddingHorizontal="20dp"
|
||||||
|
android:paddingTop="20dp"
|
||||||
|
android:paddingBottom="80dp">
|
||||||
|
|
||||||
|
<!-- 1. BARRA DE PESQUISA MODERNA -->
|
||||||
|
<androidx.cardview.widget.CardView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="56dp"
|
||||||
|
android:layout_marginBottom="24dp"
|
||||||
|
app:cardCornerRadius="28dp"
|
||||||
|
app:cardElevation="2dp">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:paddingHorizontal="16dp">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:layout_width="24dp"
|
||||||
|
android:layout_height="24dp"
|
||||||
|
android:src="@drawable/ic_search"
|
||||||
|
app:tint="@color/text_secondary" />
|
||||||
|
|
||||||
<EditText
|
<EditText
|
||||||
android:id="@+id/search_bar"
|
android:id="@+id/search_bar"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_marginStart="12dp"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:background="@null"
|
||||||
|
android:hint="Pesquisar tarefas, desafios ou utilizadores..."
|
||||||
|
android:imeOptions="actionSearch"
|
||||||
|
android:inputType="text"
|
||||||
|
android:textColor="@color/text_primary"
|
||||||
|
android:textColorHint="@color/text_secondary"
|
||||||
|
android:textSize="15sp" />
|
||||||
|
</LinearLayout>
|
||||||
|
</androidx.cardview.widget.CardView>
|
||||||
|
|
||||||
|
<!-- 2. CARD "TEU PROGRESSO" -->
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="Teu progresso esta semana"
|
||||||
|
android:textColor="@color/text_primary"
|
||||||
|
android:textSize="18sp"
|
||||||
|
android:textStyle="bold" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginBottom="16dp"
|
||||||
|
android:text="Continua consistente 🔥"
|
||||||
|
android:textColor="@color/text_secondary"
|
||||||
|
android:textSize="14sp" />
|
||||||
|
|
||||||
|
<androidx.cardview.widget.CardView
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:hint="Search..." />
|
android:layout_marginBottom="24dp"
|
||||||
|
app:cardCornerRadius="@dimen/radius_duo"
|
||||||
|
app:cardElevation="2dp">
|
||||||
|
|
||||||
<ListView
|
<LinearLayout
|
||||||
android:id="@+id/recycler_view"
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="wrap_content"
|
||||||
android:layout_below="@id/search_bar" />
|
android:orientation="vertical"
|
||||||
|
android:padding="16dp">
|
||||||
|
|
||||||
|
<com.github.mikephil.charting.charts.BarChart
|
||||||
|
android:id="@+id/weeklyChart"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="200dp" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tvEmptyState"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:gravity="center"
|
||||||
|
android:padding="32dp"
|
||||||
|
android:text="Completa tarefas para veres teu progresso 📈"
|
||||||
|
android:textColor="@color/text_secondary"
|
||||||
|
android:visibility="gone" />
|
||||||
|
</LinearLayout>
|
||||||
|
</androidx.cardview.widget.CardView>
|
||||||
|
|
||||||
|
<!-- 3. DESAFIOS POPULARES -->
|
||||||
|
<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="Desafios Populares"
|
||||||
|
android:textColor="@color/text_primary"
|
||||||
|
android:textSize="18sp"
|
||||||
|
android:textStyle="bold" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/btnSeeAllChallenges"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_alignParentEnd="true"
|
||||||
|
android:text="Ver todos"
|
||||||
|
android:textColor="@color/primary_purple"
|
||||||
|
android:textSize="14sp"
|
||||||
|
android:textStyle="bold" />
|
||||||
</RelativeLayout>
|
</RelativeLayout>
|
||||||
|
|
||||||
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
android:id="@+id/rvChallenges"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginBottom="24dp"
|
||||||
|
android:clipToPadding="false"
|
||||||
|
android:orientation="horizontal" />
|
||||||
|
|
||||||
|
<!-- 4. UTILIZADORES EM DESTAQUE -->
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginBottom="12dp"
|
||||||
|
android:text="Utilizadores em Destaque"
|
||||||
|
android:textColor="@color/text_primary"
|
||||||
|
android:textSize="18sp"
|
||||||
|
android:textStyle="bold" />
|
||||||
|
|
||||||
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
android:id="@+id/rvFeaturedUsers"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:nestedScrollingEnabled="false" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
</androidx.core.widget.NestedScrollView>
|
||||||
|
|||||||
Reference in New Issue
Block a user