ja meti o droplist nos medicamentos
This commit is contained in:
@@ -0,0 +1,18 @@
|
||||
package com.example.cuida.data.model;
|
||||
|
||||
public class Comprimido {
|
||||
public String nome;
|
||||
public String dosagem;
|
||||
|
||||
public Comprimido() {}
|
||||
|
||||
public Comprimido(String nome, String dosagem) {
|
||||
this.nome = nome;
|
||||
this.dosagem = dosagem;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return nome;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
package com.example.cuida.ui.medication;
|
||||
|
||||
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.cuida.R;
|
||||
import com.example.cuida.data.model.Comprimido;
|
||||
import java.util.List;
|
||||
|
||||
public class ComprimidoRecyclerAdapter extends RecyclerView.Adapter<ComprimidoRecyclerAdapter.ViewHolder> {
|
||||
|
||||
private List<Comprimido> pills;
|
||||
private OnItemClickListener listener;
|
||||
|
||||
public interface OnItemClickListener {
|
||||
void onItemClick(Comprimido comprimido);
|
||||
}
|
||||
|
||||
public ComprimidoRecyclerAdapter(List<Comprimido> pills, OnItemClickListener listener) {
|
||||
this.pills = pills;
|
||||
this.listener = listener;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_comprimido_search, parent, false);
|
||||
return new ViewHolder(view);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
|
||||
Comprimido pill = pills.get(position);
|
||||
holder.textName.setText(pill.nome);
|
||||
holder.itemView.setOnClickListener(v -> listener.onItemClick(pill));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return pills.size();
|
||||
}
|
||||
|
||||
public static class ViewHolder extends RecyclerView.ViewHolder {
|
||||
TextView textName;
|
||||
|
||||
public ViewHolder(@NonNull View itemView) {
|
||||
super(itemView);
|
||||
textName = itemView.findViewById(R.id.text_pill_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,6 +7,10 @@ import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.widget.EditText;
|
||||
import android.widget.TextView;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import com.google.android.material.textfield.TextInputEditText;
|
||||
import android.util.Log;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
@@ -15,10 +19,28 @@ import com.example.cuida.R;
|
||||
import com.example.cuida.data.model.Medication;
|
||||
import java.util.Calendar;
|
||||
import java.util.Locale;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
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 android.text.Editable;
|
||||
import android.text.TextWatcher;
|
||||
import com.example.cuida.data.model.Comprimido;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.Toast;
|
||||
|
||||
public class MedicationDialog extends DialogFragment {
|
||||
|
||||
private EditText editName, editNotes;
|
||||
private TextInputEditText editName;
|
||||
private RecyclerView recyclerResults;
|
||||
private ComprimidoRecyclerAdapter recyclerAdapter;
|
||||
private List<Comprimido> searchResults = new ArrayList<>();
|
||||
private List<Comprimido> fullPillsList = new ArrayList<>();
|
||||
private DatabaseReference medicationRef;
|
||||
private EditText editNotes;
|
||||
private android.widget.RadioButton radioOral, radioTopical, radioInhalatory;
|
||||
private android.widget.RadioGroup radioGroupRoute;
|
||||
private TextView textTime;
|
||||
@@ -54,6 +76,7 @@ public class MedicationDialog extends DialogFragment {
|
||||
View view = inflater.inflate(R.layout.dialog_add_medication, null);
|
||||
|
||||
editName = view.findViewById(R.id.edit_med_name);
|
||||
recyclerResults = view.findViewById(R.id.recycler_search_results);
|
||||
editNotes = view.findViewById(R.id.edit_med_notes);
|
||||
textTime = view.findViewById(R.id.text_med_time);
|
||||
|
||||
@@ -62,6 +85,44 @@ public class MedicationDialog extends DialogFragment {
|
||||
radioTopical = view.findViewById(R.id.radio_topical);
|
||||
radioInhalatory = view.findViewById(R.id.radio_inhalatory);
|
||||
|
||||
final android.content.Context currentContext = getContext();
|
||||
if (currentContext != null) {
|
||||
recyclerAdapter = new ComprimidoRecyclerAdapter(searchResults, selected -> {
|
||||
editName.setText(selected.nome);
|
||||
editName.setSelection(selected.nome.length());
|
||||
|
||||
// Adiciona a dosagem/informação ao campo de notas automaticamente
|
||||
if (selected.dosagem != null && !selected.dosagem.isEmpty()) {
|
||||
editNotes.setText(selected.dosagem);
|
||||
}
|
||||
|
||||
recyclerResults.setVisibility(View.GONE);
|
||||
searchResults.clear();
|
||||
});
|
||||
recyclerResults.setLayoutManager(new LinearLayoutManager(currentContext));
|
||||
recyclerResults.setAdapter(recyclerAdapter);
|
||||
|
||||
String dbUrl = "https://cuidamais-7b904-default-rtdb.firebaseio.com/";
|
||||
medicationRef = FirebaseDatabase.getInstance(dbUrl).getReference("medication");
|
||||
|
||||
// Carregar todos os medicamentos uma única vez para filtragem local rápida
|
||||
fetchAllMedsOnce();
|
||||
|
||||
editName.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) {
|
||||
filterMedsLocally(s.toString().trim());
|
||||
}
|
||||
@Override public void afterTextChanged(Editable s) {}
|
||||
});
|
||||
}
|
||||
|
||||
radioGroupRoute = view.findViewById(R.id.radio_group_route);
|
||||
radioOral = view.findViewById(R.id.radio_oral);
|
||||
radioTopical = view.findViewById(R.id.radio_topical);
|
||||
radioInhalatory = view.findViewById(R.id.radio_inhalatory);
|
||||
|
||||
// Set up TimePicker
|
||||
textTime.setOnClickListener(v -> showTimePicker());
|
||||
|
||||
@@ -186,4 +247,94 @@ public class MedicationDialog extends DialogFragment {
|
||||
String time = String.format(Locale.getDefault(), "%02d:%02d", hourOfDay, minute);
|
||||
textTime.setText(time);
|
||||
}
|
||||
|
||||
private void fetchAllMedsOnce() {
|
||||
String dbUrl = "https://cuidamais-7b904-default-rtdb.firebaseio.com/";
|
||||
DatabaseReference rootRef = FirebaseDatabase.getInstance(dbUrl).getReference();
|
||||
String[] nodes = {"medication", "medicamentos", "Medicamentos", "comprimidos"};
|
||||
|
||||
fullPillsList.clear();
|
||||
|
||||
// 1. Tentar nos nós específicos
|
||||
for (String node : nodes) {
|
||||
rootRef.child(node).addListenerForSingleValueEvent(new ValueEventListener() {
|
||||
@Override
|
||||
public void onDataChange(@NonNull DataSnapshot snapshot) {
|
||||
if (snapshot.exists()) {
|
||||
parseSnapshot(snapshot, "Nó: " + node);
|
||||
}
|
||||
}
|
||||
@Override public void onCancelled(@NonNull DatabaseError error) {}
|
||||
});
|
||||
}
|
||||
|
||||
// 2. Tentar também na raiz (caso os medicamentos estejam diretamente no topo)
|
||||
rootRef.limitToFirst(50).addListenerForSingleValueEvent(new ValueEventListener() {
|
||||
@Override
|
||||
public void onDataChange(@NonNull DataSnapshot snapshot) {
|
||||
if (snapshot.exists()) {
|
||||
parseSnapshot(snapshot, "Raiz");
|
||||
}
|
||||
}
|
||||
@Override public void onCancelled(@NonNull DatabaseError error) {}
|
||||
});
|
||||
}
|
||||
|
||||
private void parseSnapshot(DataSnapshot snapshot, String source) {
|
||||
int count = 0;
|
||||
for (DataSnapshot child : snapshot.getChildren()) {
|
||||
String name = child.child("nome").getValue(String.class);
|
||||
if (name == null) name = child.child("name").getValue(String.class);
|
||||
if (name == null && !(child.getValue() instanceof java.util.Map)) {
|
||||
// Se o valor for a própria string (ex: "Paracetamol")
|
||||
name = child.getValue() instanceof String ? (String) child.getValue() : null;
|
||||
}
|
||||
if (name == null) name = child.getKey();
|
||||
|
||||
String dosage = child.child("dosagem").getValue(String.class);
|
||||
if (dosage == null) dosage = child.child("dosage").getValue(String.class);
|
||||
if (dosage == null) dosage = "";
|
||||
|
||||
if (name != null && !name.isEmpty()) {
|
||||
boolean exists = false;
|
||||
for (Comprimido p : fullPillsList) {
|
||||
if (name.equals(p.nome)) { exists = true; break; }
|
||||
}
|
||||
if (!exists) {
|
||||
fullPillsList.add(new Comprimido(name, dosage));
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (count > 0 && getContext() != null) {
|
||||
Log.d("FirebaseSearch", "Carregados " + count + " de " + source);
|
||||
// Toast.makeText(getContext(), "Fonte: " + source + " (" + count + ")", Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}
|
||||
|
||||
private void filterMedsLocally(String query) {
|
||||
searchResults.clear();
|
||||
if (query.isEmpty()) {
|
||||
recyclerResults.setVisibility(View.GONE);
|
||||
recyclerAdapter.notifyDataSetChanged();
|
||||
return;
|
||||
}
|
||||
|
||||
String lowerQuery = query.toLowerCase();
|
||||
for (Comprimido p : fullPillsList) {
|
||||
if (p.nome != null && p.nome.toLowerCase().contains(lowerQuery)) {
|
||||
searchResults.add(p);
|
||||
}
|
||||
}
|
||||
|
||||
recyclerAdapter.notifyDataSetChanged();
|
||||
recyclerResults.setVisibility(searchResults.isEmpty() ? View.GONE : View.VISIBLE);
|
||||
}
|
||||
|
||||
private void handleError(DatabaseError error) {
|
||||
Log.e("FirebaseSearch", "Erro: " + error.getMessage());
|
||||
if (getContext() != null) {
|
||||
Toast.makeText(getContext(), "Erro no Firebase: " + error.getMessage(), Toast.LENGTH_LONG).show();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -107,21 +107,14 @@ public class ScheduleAppointmentFragment extends Fragment {
|
||||
}
|
||||
|
||||
private void setupDoctorSpinner() {
|
||||
java.util.List<String> doctors = new java.util.ArrayList<>();
|
||||
doctors.add("Dr. Paulo Silva - Clínica Geral");
|
||||
doctors.add("Dra. Maria Mendes - Pediatria (Crianças)");
|
||||
doctors.add("Dr. Rui Costa - Cardiologia (Coração)");
|
||||
doctors.add("Dra. Ana Ferreira - Dermatologia (Pele)");
|
||||
doctors.add("Dr. João Almeida - Ortopedia (Ossos)");
|
||||
doctors.add("Dra. Sofia Martins - Oftalmologia (Olhos)");
|
||||
doctors.add("Dr. Pedro Oliveira - Psiquiatria (Saúde Mental)");
|
||||
doctors.add("Dra. Inês Cardoso - Ginecologia (Mulher)");
|
||||
doctors.add("Dr. Tiago Santos - Neurologia (Cérebro)");
|
||||
|
||||
java.util.Collections.shuffle(doctors); // Randomize the names as requested
|
||||
|
||||
ArrayAdapter<String> adapter = new ArrayAdapter<>(requireContext(), android.R.layout.simple_dropdown_item_1line, doctors);
|
||||
spinnerDoctor.setAdapter(adapter);
|
||||
scheduleViewModel.getDoctorsList().observe(getViewLifecycleOwner(), doctors -> {
|
||||
if (doctors != null) {
|
||||
java.util.List<String> shuffledDoctors = new java.util.ArrayList<>(doctors);
|
||||
java.util.Collections.shuffle(shuffledDoctors); // Randomize the names as requested
|
||||
ArrayAdapter<String> adapter = new ArrayAdapter<>(requireContext(), android.R.layout.simple_dropdown_item_1line, shuffledDoctors);
|
||||
spinnerDoctor.setAdapter(adapter);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void setupDatePicker() {
|
||||
|
||||
@@ -26,11 +26,46 @@ public class ScheduleViewModel extends AndroidViewModel {
|
||||
private final MutableLiveData<String> selectedTime = new MutableLiveData<>();
|
||||
private final MutableLiveData<List<TimeSlot>> timeSlots = new MutableLiveData<>();
|
||||
private final MutableLiveData<Boolean> saveSuccess = new MutableLiveData<>();
|
||||
private final MutableLiveData<List<String>> doctorsList = new MutableLiveData<>(new ArrayList<>());
|
||||
|
||||
public ScheduleViewModel(@NonNull Application application) {
|
||||
super(application);
|
||||
db = FirebaseFirestore.getInstance();
|
||||
auth = FirebaseAuth.getInstance();
|
||||
fetchDoctors();
|
||||
}
|
||||
|
||||
private void fetchDoctors() {
|
||||
db.collection("medicos")
|
||||
.get()
|
||||
.addOnCompleteListener(task -> {
|
||||
if (task.isSuccessful() && task.getResult() != null) {
|
||||
List<String> docs = new ArrayList<>();
|
||||
for (QueryDocumentSnapshot document : task.getResult()) {
|
||||
String name = document.getString("nome");
|
||||
String specialty = document.getString("especialidade");
|
||||
String gender = document.getString("genero");
|
||||
|
||||
if (name != null) {
|
||||
String displayName = name;
|
||||
if (specialty != null && !specialty.isEmpty()) {
|
||||
displayName += " - " + specialty;
|
||||
}
|
||||
if (!displayName.startsWith("Dr.") && !displayName.startsWith("Dra.")) {
|
||||
if ("Feminino".equalsIgnoreCase(gender)) {
|
||||
displayName = "Dra. " + displayName;
|
||||
} else {
|
||||
displayName = "Dr. " + displayName;
|
||||
}
|
||||
}
|
||||
docs.add(displayName);
|
||||
}
|
||||
}
|
||||
doctorsList.postValue(docs);
|
||||
} else {
|
||||
Log.e("ScheduleViewModel", "Error getting doctors", task.getException());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void setDate(int year, int month, int dayOfMonth) {
|
||||
@@ -66,6 +101,10 @@ public class ScheduleViewModel extends AndroidViewModel {
|
||||
return saveSuccess;
|
||||
}
|
||||
|
||||
public LiveData<List<String>> getDoctorsList() {
|
||||
return doctorsList;
|
||||
}
|
||||
|
||||
private void loadTimeSlots(String date) {
|
||||
// Init slots immediately to prevent "disappearing" hours while waiting for
|
||||
// network.
|
||||
|
||||
6
app/src/main/res/drawable/bg_search_results.xml
Normal file
6
app/src/main/res/drawable/bg_search_results.xml
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<solid android:color="#FFFFFF" />
|
||||
<stroke android:width="1dp" android:color="#DDDDDD" />
|
||||
<corners android:radius="8dp" />
|
||||
</shape>
|
||||
@@ -5,25 +5,49 @@
|
||||
android:orientation="vertical"
|
||||
android:padding="24dp">
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
<FrameLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:hint="Nome do Medicamento"
|
||||
android:layout_marginBottom="16dp">
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<com.google.android.material.textfield.TextInputEditText
|
||||
android:id="@+id/edit_med_name"
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:inputType="textCapWords" />
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:text="Horário"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="14sp"
|
||||
android:layout_marginBottom="4dp"/>
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:id="@+id/layout_med_name"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
|
||||
android:hint="Nome do Medicamento"
|
||||
android:layout_marginBottom="8dp">
|
||||
|
||||
<com.google.android.material.textfield.TextInputEditText
|
||||
android:id="@+id/edit_med_name"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:inputType="textCapWords" />
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
<TextView
|
||||
android:text="Horário"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="14sp"
|
||||
android:layout_marginBottom="4dp"/>
|
||||
|
||||
<!-- O resto do conteúdo do diálogo continua aqui em baixo -->
|
||||
</LinearLayout>
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/recycler_search_results"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="200dp"
|
||||
android:layout_marginTop="60dp"
|
||||
android:visibility="gone"
|
||||
android:elevation="8dp"
|
||||
android:background="@drawable/bg_search_results" />
|
||||
</FrameLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/text_med_time"
|
||||
|
||||
16
app/src/main/res/layout/item_comprimido_search.xml
Normal file
16
app/src/main/res/layout/item_comprimido_search.xml
Normal file
@@ -0,0 +1,16 @@
|
||||
<?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="vertical"
|
||||
android:padding="12dp">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/text_pill_name"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="16sp"
|
||||
android:textStyle="bold"
|
||||
android:textColor="@color/primary_color" />
|
||||
|
||||
</LinearLayout>
|
||||
Reference in New Issue
Block a user