diff --git a/.idea/deploymentTargetSelector.xml b/.idea/deploymentTargetSelector.xml
index 4ee0cbf..94ca3b7 100644
--- a/.idea/deploymentTargetSelector.xml
+++ b/.idea/deploymentTargetSelector.xml
@@ -3,8 +3,8 @@
-
-
+
+
@@ -27,7 +27,28 @@
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/build.gradle b/app/build.gradle
index 5f4dffa..23c6f7d 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -8,7 +8,7 @@ android {
defaultConfig {
applicationId "com.example.coach"
- minSdk 16
+ minSdk 21
targetSdk 36
versionCode 1
versionName "1.0"
@@ -34,6 +34,7 @@ dependencies {
implementation libs.material
implementation libs.activity
implementation libs.constraintlayout
+ implementation libs.recyclerview
testImplementation libs.junit
androidTestImplementation libs.ext.junit
androidTestImplementation libs.espresso.core
diff --git a/app/src/androidTest/java/com/example/coach/view/MainActivityTest.java b/app/src/androidTest/java/com/example/coach/view/CalculActivityTest.java
similarity index 90%
rename from app/src/androidTest/java/com/example/coach/view/MainActivityTest.java
rename to app/src/androidTest/java/com/example/coach/view/CalculActivityTest.java
index f832232..e00961b 100644
--- a/app/src/androidTest/java/com/example/coach/view/MainActivityTest.java
+++ b/app/src/androidTest/java/com/example/coach/view/CalculActivityTest.java
@@ -12,15 +12,14 @@ import static androidx.test.espresso.action.ViewActions.click;
import static androidx.test.espresso.action.ViewActions.typeText;
import static androidx.test.espresso.action.ViewActions.closeSoftKeyboard;
import static androidx.test.espresso.matcher.ViewMatchers.withId;
-import static androidx.test.espresso.assertion.ViewAssertions.matches;
import static androidx.test.espresso.matcher.ViewMatchers.withText;
import com.example.coach.R;
@RunWith(AndroidJUnit4.class)
-public class MainActivityTest {
+public class CalculActivityTest {
@Rule
- public ActivityScenarioRule activityRule = new ActivityScenarioRule<>(MainActivity.class);
+ public ActivityScenarioRule activityRule = new ActivityScenarioRule<>(CalculActivity.class);
@Test
public void testCalculIMG(){
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 3e8cf32..d72a35e 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -2,6 +2,8 @@
+
+
+
+ android:exported="true"
+ android:launchMode="singleTop">
+
-
+
\ No newline at end of file
diff --git a/app/src/main/java/com/example/coach/api/HelperApi.java b/app/src/main/java/com/example/coach/api/HelperApi.java
new file mode 100644
index 0000000..8985b28
--- /dev/null
+++ b/app/src/main/java/com/example/coach/api/HelperApi.java
@@ -0,0 +1,45 @@
+package com.example.coach.api;
+
+import android.util.Log;
+
+import com.example.coach.model.Profil;
+
+import java.util.List;
+
+import retrofit2.Call;
+import retrofit2.Callback;
+import retrofit2.Response;
+
+public class HelperApi {
+ private static final IRequestApi api = CoachApi.getRetrofit().create(IRequestApi.class);
+
+ public static IRequestApi getApi()
+ {
+ return api;
+ }
+
+ public static void call(Call> call, ICallbackApi callback)
+ {
+ call.enqueue(new Callback>() {
+ @Override
+ public void onResponse(Call> call, Response> response) {
+ Log.d("API", "code : " + response.body().getCode() +
+ " message : " + response.body().getMessage() +
+ " result : " + response.body().getResult()
+ );
+ if (response.isSuccessful() && response.body() != null) {
+ callback.onSuccess(response.body().getResult());
+ } else {
+ callback.onError();
+ Log.e("API", "Erreur API: " + response.code());
+ }
+ }
+
+ @Override
+ public void onFailure(Call> call, Throwable throwable) {
+ callback.onError();
+ Log.e("API", "Erreur API", throwable);
+ }
+ });
+ }
+}
diff --git a/app/src/main/java/com/example/coach/api/ICallbackApi.java b/app/src/main/java/com/example/coach/api/ICallbackApi.java
new file mode 100644
index 0000000..b9fa9bf
--- /dev/null
+++ b/app/src/main/java/com/example/coach/api/ICallbackApi.java
@@ -0,0 +1,6 @@
+package com.example.coach.api;
+
+public interface ICallbackApi {
+ void onSuccess(T result);
+ void onError();
+}
diff --git a/app/src/main/java/com/example/coach/api/IRequestApi.java b/app/src/main/java/com/example/coach/api/IRequestApi.java
index 13967ee..0cbc9c6 100644
--- a/app/src/main/java/com/example/coach/api/IRequestApi.java
+++ b/app/src/main/java/com/example/coach/api/IRequestApi.java
@@ -5,10 +5,12 @@ import com.example.coach.model.Profil;
import java.util.List;
import retrofit2.Call;
+import retrofit2.http.DELETE;
import retrofit2.http.Field;
import retrofit2.http.FormUrlEncoded;
import retrofit2.http.GET;
import retrofit2.http.POST;
+import retrofit2.http.Path;
public interface IRequestApi {
@GET("profil")
@@ -17,4 +19,7 @@ public interface IRequestApi {
@FormUrlEncoded
@POST("profil")
Call> creerProfil(@Field("champs") String profilJson);
+
+ @DELETE("profil/{champs}")
+ Call> supprProfil(@Path(value = "champs", encoded = true) String profilJson);
}
diff --git a/app/src/main/java/com/example/coach/contract/IAllView.java b/app/src/main/java/com/example/coach/contract/IAllView.java
new file mode 100644
index 0000000..9bf7e20
--- /dev/null
+++ b/app/src/main/java/com/example/coach/contract/IAllView.java
@@ -0,0 +1,5 @@
+package com.example.coach.contract;
+
+public interface IAllView {
+ void afficherMessage(String message);
+}
diff --git a/app/src/main/java/com/example/coach/contract/ICalculView.java b/app/src/main/java/com/example/coach/contract/ICalculView.java
index cb0d94b..e76e396 100644
--- a/app/src/main/java/com/example/coach/contract/ICalculView.java
+++ b/app/src/main/java/com/example/coach/contract/ICalculView.java
@@ -3,7 +3,7 @@ package com.example.coach.contract;
/**
* Contrat pour que le CalculPresenter puisse envoyer des infos à la vue
*/
-public interface ICalculView {
+public interface ICalculView extends IAllView{
/**
* Méthode permettant le transfert des résultats vers la vue
* @param image nom du fichier du smiley
diff --git a/app/src/main/java/com/example/coach/contract/IHistoView.java b/app/src/main/java/com/example/coach/contract/IHistoView.java
new file mode 100644
index 0000000..6ce6a36
--- /dev/null
+++ b/app/src/main/java/com/example/coach/contract/IHistoView.java
@@ -0,0 +1,10 @@
+package com.example.coach.contract;
+
+import com.example.coach.model.Profil;
+
+import java.util.List;
+
+public interface IHistoView extends IAllView {
+ void afficherListe(List profils);
+ void transfertProfil(Profil profil);
+}
diff --git a/app/src/main/java/com/example/coach/model/Profil.java b/app/src/main/java/com/example/coach/model/Profil.java
index 9729238..861c5ca 100644
--- a/app/src/main/java/com/example/coach/model/Profil.java
+++ b/app/src/main/java/com/example/coach/model/Profil.java
@@ -1,11 +1,12 @@
package com.example.coach.model;
+import java.io.Serializable;
import java.util.Date;
/**
* Classe métier contenant les informations d'un profil
*/
-public class Profil {
+public class Profil implements Serializable {
private static final int MIN_FEMME = 25;
private static final int MAX_FEMME = 30;
private static final int MIN_HOMME = 15;
@@ -83,7 +84,7 @@ public class Profil {
* @return Valeur de l'img
*/
public double getImg(){
- return this.img;
+ return calculImg();
}
/**
diff --git a/app/src/main/java/com/example/coach/presenter/CalculPresenter.java b/app/src/main/java/com/example/coach/presenter/CalculPresenter.java
index 1a86538..608bc17 100644
--- a/app/src/main/java/com/example/coach/presenter/CalculPresenter.java
+++ b/app/src/main/java/com/example/coach/presenter/CalculPresenter.java
@@ -5,6 +5,8 @@ import android.util.Log;
import androidx.annotation.NonNull;
import com.example.coach.api.CoachApi;
+import com.example.coach.api.HelperApi;
+import com.example.coach.api.ICallbackApi;
import com.example.coach.api.IRequestApi;
import com.example.coach.api.ResponseApi;
import com.example.coach.contract.ICalculView;
@@ -43,53 +45,51 @@ public class CalculPresenter {
public void creerProfil(Integer sexe, Integer poids, Integer taille, Integer age)
{
Profil profil = new Profil(poids, taille, age, sexe, new Date());
+ vue.AfficherResultat(profil.getImage(), profil.getImg(), profil.getMessage(), profil.normal());
String profilJson = CoachApi.getGson().toJson(profil);
-
- IRequestApi api = CoachApi.getRetrofit().create(IRequestApi.class);
- Call> call = api.creerProfil(profilJson);
-
- call.enqueue(new Callback>() {
+ HelperApi.call(HelperApi.getApi().creerProfil(profilJson), new ICallbackApi() {
@Override
- public void onResponse(Call> call, Response> response) {
- Log.d("API", "code : " + response.body().getCode() +
- " message : " + response.body().getMessage() +
- " result : " + response.body().getResult()
- );
- if(response.isSuccessful() && response.body().getResult() == 1){
- vue.AfficherResultat(profil.getImage(), profil.getImg(), profil.getMessage(), profil.normal());
+ public void onSuccess(Integer result) {
+ if (result == 1) {
+ vue.afficherMessage("profil enregistré");
}else{
- Log.e("API", "Erreur API: " + response.code());
+ vue.afficherMessage("échec enregistrement profil");
}
}
@Override
- public void onFailure(Call> call, @NonNull Throwable throwable) {
- Log.e("API", "Échec d'accès à l'api", throwable);
+ public void onError() {
+ vue.afficherMessage("échec enregistrement profil");
}
});
}
public void chargerDernierProfil()
{
- IRequestApi api = CoachApi.getRetrofit().create(IRequestApi.class);
- Call>> call = api.getProfils();
-
- call.enqueue(new Callback>>() {
+ IRequestApi api = HelperApi.getApi();
+ HelperApi.call(api.getProfils(), new ICallbackApi>() {
@Override
- public void onResponse(Call>> call, Response>> response) {
- List profils = response.body().getResult();
- if(profils != null && !profils.isEmpty()){
- Profil dernier = Collections.max(
- profils,
- (p1, p2) -> p1.getDateMesure().compareTo(p2.getDateMesure())
- );
- vue.remplirChamps(dernier.getPoids(), dernier.getTaille(), dernier.getAge(), dernier.getSexe());
+ public void onSuccess(List result) {
+ if(result != null){
+ List profils = result;
+ if (profils != null && !profils.isEmpty()) {
+ // récupérer le plus récent
+ Profil dernier = Collections.max(profils,
+ (p1, p2) -> p1.getDateMesure().compareTo(p2.getDateMesure())
+ );
+ vue.remplirChamps(dernier.getPoids(), dernier.getTaille(),
+ dernier.getAge(), dernier.getSexe());
+ }else{
+ vue.afficherMessage("échec récupération dernier profil");
+ }
+ }else{
+ vue.afficherMessage("échec récupération dernier profil");
}
}
@Override
- public void onFailure(Call>> call, Throwable throwable) {
- Log.e("API", "Échec d'accès à l'api", throwable);
+ public void onError() {
+ vue.afficherMessage("échec récupération dernier profil");
}
});
}
diff --git a/app/src/main/java/com/example/coach/presenter/HistoPresenter.java b/app/src/main/java/com/example/coach/presenter/HistoPresenter.java
new file mode 100644
index 0000000..f4835a0
--- /dev/null
+++ b/app/src/main/java/com/example/coach/presenter/HistoPresenter.java
@@ -0,0 +1,74 @@
+package com.example.coach.presenter;
+
+import android.util.Log;
+
+import com.example.coach.api.CoachApi;
+import com.example.coach.api.HelperApi;
+import com.example.coach.api.ICallbackApi;
+import com.example.coach.api.IRequestApi;
+import com.example.coach.api.ResponseApi;
+import com.example.coach.contract.IHistoView;
+import com.example.coach.model.Profil;
+
+import java.util.Collections;
+import java.util.List;
+
+import retrofit2.Call;
+import retrofit2.Callback;
+import retrofit2.Response;
+
+public class HistoPresenter {
+ private IHistoView vue;
+
+ public HistoPresenter(IHistoView vue)
+ {
+ this.vue = vue;
+ }
+
+ public void chargerProfils()
+ {
+ HelperApi.call(HelperApi.getApi().getProfils(), new ICallbackApi>() {
+ @Override
+ public void onSuccess(List result) {
+ if(result != null){
+ List profils = result;
+ Collections.sort(profils, (p1, p2) -> p2.getDateMesure().compareTo(p1.getDateMesure()));
+ vue.afficherListe(profils);
+ }else{
+ vue.afficherMessage("échec récupération des derniers profils");
+ }
+ }
+
+ @Override
+ public void onError() {
+ vue.afficherMessage("échec récupération des derniers profils");
+ }
+ });
+ }
+
+ public void supprProfil(Profil profil, ICallbackApi callback)
+ {
+ String profilJson = CoachApi.getGson().toJson(profil);
+ HelperApi.call(HelperApi.getApi().supprProfil(profilJson), new ICallbackApi() {
+ @Override
+ public void onSuccess(Integer result) {
+ if (result == 1) {
+ vue.afficherMessage("profil supprimé");
+ callback.onSuccess(null);
+ }else{
+ vue.afficherMessage("échec suppression profil");
+ }
+ }
+
+ @Override
+ public void onError() {
+ vue.afficherMessage("échec suppression profil");
+ }
+ });
+ }
+
+ public void transfertProfil(Profil profil)
+ {
+ vue.transfertProfil(profil);
+ }
+}
diff --git a/app/src/main/java/com/example/coach/view/CalculActivity.java b/app/src/main/java/com/example/coach/view/CalculActivity.java
new file mode 100644
index 0000000..f6f713f
--- /dev/null
+++ b/app/src/main/java/com/example/coach/view/CalculActivity.java
@@ -0,0 +1,167 @@
+package com.example.coach.view;
+
+import android.graphics.Color;
+import android.os.Bundle;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.ImageView;
+import android.widget.RadioButton;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import androidx.activity.EdgeToEdge;
+import androidx.appcompat.app.AppCompatActivity;
+import androidx.core.graphics.Insets;
+import androidx.core.view.ViewCompat;
+import androidx.core.view.WindowInsetsCompat;
+
+import com.example.coach.R;
+import com.example.coach.contract.ICalculView;
+import com.example.coach.model.Profil;
+import com.example.coach.presenter.CalculPresenter;
+
+/**
+ * Activity qui permet le calcul de l'img
+ */
+public class CalculActivity extends AppCompatActivity implements ICalculView {
+
+ private EditText txtPoids;
+ private EditText txtTaille;
+ private EditText txtAge;
+ private RadioButton rdHomme;
+ private RadioButton rdFemme;
+ private TextView lblIMG;
+ private ImageView imgSmiley;
+ private Button btnCalc;
+
+ private CalculPresenter presenter;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ EdgeToEdge.enable(this);
+ setContentView(R.layout.activity_calcul);
+ ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> {
+ Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());
+ v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);
+ return insets;
+ });
+ init();
+ }
+
+ /**
+ * Méthode permettant l'affichage du résultat du calcul de l'img
+ * @param image nom du fichier drawable pour le smiley
+ * @param img valeur de l'img
+ * @param message message à afficher
+ * @param normal faux si l'img n'est pas normal, vrai dans le cas inverse
+ */
+ @Override
+ public void AfficherResultat(String image, double img, String message, boolean normal) {
+ int iamgeId = getResources().getIdentifier(image, "drawable", getPackageName());
+ String texte = String.format("%.01f", img) + " : IMG " + message;
+
+ if(iamgeId == 0){
+ imgSmiley.setImageResource(R.drawable.normal);
+ }else{
+ imgSmiley.setImageResource(iamgeId);
+ }
+ lblIMG.setText(texte);
+ if(!normal){
+ lblIMG.setTextColor(Color.RED);
+ }else{
+ lblIMG.setTextColor(Color.GREEN);
+ }
+ }
+
+ /**
+ * @param poids poids stocké
+ * @param taille taille stockée
+ * @param age âge stocké
+ * @param sexe sexe stocké
+ */
+ @Override
+ public void remplirChamps(Integer poids, Integer taille, Integer age, Integer sexe) {
+ txtPoids.setText(poids.toString());
+ txtTaille.setText(taille.toString());
+ txtAge.setText(age.toString());
+
+ if(sexe == 1){
+ rdHomme.setChecked(true);
+ }else{
+ rdFemme.setChecked(true);
+ }
+ }
+
+ /**
+ * Traitements à réaliser lors du lancement de l'application
+ */
+ private void init()
+ {
+ chargeObjetsGraphiques();
+ presenter = new CalculPresenter(this);
+ btnCalc.setOnClickListener(v -> btnCalcClic());
+ recupProfil();
+ }
+
+ /**
+ * Récupère les objets graphiques
+ */
+ private void chargeObjetsGraphiques()
+ {
+ txtPoids = (EditText) findViewById(R.id.txtPoids);
+ txtTaille = (EditText) findViewById(R.id.txtTaille);
+ txtAge = (EditText) findViewById(R.id.txtAge);
+
+ rdHomme = (RadioButton) findViewById(R.id.rdHomme);
+ rdFemme = (RadioButton) findViewById(R.id.rdFemme);
+
+ lblIMG = (TextView) findViewById(R.id.lblResultat);
+
+ imgSmiley = (ImageView) findViewById(R.id.imgSmiley);
+
+ btnCalc = (Button) findViewById(R.id.btnCalc);
+ }
+
+ /**
+ * Traitements à réaliser lors du clic sur le bouton
+ */
+ private void btnCalcClic()
+ {
+ int poids = 0, taille = 0, age = 0, sexe = 0;
+
+ try {
+ poids = Integer.parseInt(txtPoids.getText().toString());
+ taille = Integer.parseInt(txtTaille.getText().toString());
+ age = Integer.parseInt(txtAge.getText().toString());
+ }catch (Exception ignored){}
+
+ if(rdHomme.isChecked()){
+ sexe = 1;
+ }
+
+ if(poids == 0 || taille == 0 || age == 0){
+ Toast.makeText(this, "Veuillez remplir tous les champs", Toast.LENGTH_SHORT).show();
+ }else{
+ presenter.creerProfil(sexe, poids, taille, age);
+ }
+ }
+
+ /**
+ * @param message
+ */
+ @Override
+ public void afficherMessage(String message) {
+ Toast.makeText(this, message, Toast.LENGTH_SHORT).show();
+ }
+
+ private void recupProfil()
+ {
+ Profil profil = (Profil) getIntent().getSerializableExtra("profil");
+ if(profil != null){
+ remplirChamps(profil.getPoids(), profil.getTaille(), profil.getAge(), profil.getSexe());
+ }else{
+ presenter.chargerDernierProfil();
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/example/coach/view/HistoActivity.java b/app/src/main/java/com/example/coach/view/HistoActivity.java
new file mode 100644
index 0000000..56df044
--- /dev/null
+++ b/app/src/main/java/com/example/coach/view/HistoActivity.java
@@ -0,0 +1,74 @@
+package com.example.coach.view;
+
+import android.content.Intent;
+import android.os.Bundle;
+import android.widget.Toast;
+
+import androidx.activity.EdgeToEdge;
+import androidx.appcompat.app.AppCompatActivity;
+import androidx.core.graphics.Insets;
+import androidx.core.view.ViewCompat;
+import androidx.core.view.WindowInsetsCompat;
+import androidx.recyclerview.widget.LinearLayoutManager;
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.example.coach.R;
+import com.example.coach.contract.IHistoView;
+import com.example.coach.model.Profil;
+import com.example.coach.presenter.HistoPresenter;
+
+import java.util.List;
+
+public class HistoActivity extends AppCompatActivity implements IHistoView {
+ HistoPresenter presenter;
+
+ private void init()
+ {
+ presenter = new HistoPresenter(this);
+ presenter.chargerProfils();
+ }
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ EdgeToEdge.enable(this);
+ setContentView(R.layout.activity_histo);
+ ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> {
+ Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());
+ v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);
+ init();
+ return insets;
+ });
+ }
+
+ /**
+ * @param profils
+ */
+ @Override
+ public void afficherListe(List profils) {
+ if(profils != null){
+ RecyclerView lstHisto = (RecyclerView) findViewById(R.id.lstHisto);
+ HistoListAdapter adapter = new HistoListAdapter(profils, HistoActivity.this);
+ lstHisto.setAdapter(adapter);
+ lstHisto.setLayoutManager(new LinearLayoutManager(HistoActivity.this));
+ }
+ }
+
+ /**
+ * @param profil
+ */
+ @Override
+ public void transfertProfil(Profil profil) {
+ Intent intent = new Intent(HistoActivity.this, CalculActivity.class);
+ intent.putExtra("profil", profil);
+ startActivity(intent);
+ }
+
+ /**
+ * @param message
+ */
+ @Override
+ public void afficherMessage(String message) {
+ Toast.makeText(this, message, Toast.LENGTH_SHORT).show();
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/example/coach/view/HistoListAdapter.java b/app/src/main/java/com/example/coach/view/HistoListAdapter.java
new file mode 100644
index 0000000..e2d1ca2
--- /dev/null
+++ b/app/src/main/java/com/example/coach/view/HistoListAdapter.java
@@ -0,0 +1,128 @@
+package com.example.coach.view;
+
+import android.content.Context;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ImageButton;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import androidx.annotation.NonNull;
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.example.coach.R;
+import com.example.coach.api.ICallbackApi;
+import com.example.coach.contract.IHistoView;
+import com.example.coach.model.Profil;
+import com.example.coach.presenter.HistoPresenter;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.List;
+import java.util.Locale;
+
+public class HistoListAdapter extends RecyclerView.Adapter {
+
+ private List profils;
+ private IHistoView vue;
+
+ /**
+ * Retourne une ligne de la liste
+ * @param parent The ViewGroup into which the new View will be added after it is bound to
+ * an adapter position.
+ * @param viewType The view type of the new View.
+ * @return
+ */
+ @NonNull
+ @Override
+ public HistoListAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
+ Context parentContext = parent.getContext();
+ LayoutInflater layout = LayoutInflater.from(parentContext);
+ View view = layout.inflate(R.layout.layout_list_histo, parent, false);
+
+ return new HistoListAdapter.ViewHolder(view);
+ }
+
+ /**
+ * Rempli une ligne
+ * @param holder The ViewHolder which should be updated to represent the contents of the
+ * item at the given position in the data set.
+ * @param position The position of the item within the adapter's data set.
+ */
+ @Override
+ public void onBindViewHolder(@NonNull HistoListAdapter.ViewHolder holder, int position) {
+ Double img = profils.get(position).getImg();
+ String img1desimal = String.format("%.01f", img);
+ holder.txtListIMG.setText(img1desimal);
+
+ Date dateMesure = profils.get(position).getDateMesure();
+ SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss", Locale.getDefault());
+ String dateFormatee = sdf.format(dateMesure);
+ holder.txtListDate.setText(dateFormatee);
+ }
+
+ /**
+ * Compte le nombre de lignes
+ * @return int
+ */
+ @Override
+ public int getItemCount() {
+ return profils.size();
+ }
+
+ public HistoListAdapter(List profils, IHistoView vue)
+ {
+ this.profils = profils;
+ this.vue = vue;
+ }
+
+ public class ViewHolder extends RecyclerView.ViewHolder{
+ final TextView txtListDate;
+ final TextView txtListIMG;
+ final ImageButton btnListSuppr;
+
+ HistoPresenter presenter;
+ public ViewHolder(@NonNull View itemView) {
+ super(itemView);
+
+ txtListDate = (TextView) itemView.findViewById(R.id.txtListDate);
+ txtListIMG = (TextView) itemView.findViewById(R.id.txtListIMG);
+ btnListSuppr = (ImageButton) itemView.findViewById(R.id.btnListSuppr);
+ init();
+ }
+
+ private void btnListSuppr_clic()
+ {
+ int position = getBindingAdapterPosition();
+ presenter.supprProfil(profils.get(position), new ICallbackApi() {
+ @Override
+ public void onSuccess(Void result) {
+ profils.remove(position);
+ notifyItemRemoved(position);
+ }
+
+ @Override
+ public void onError() {
+
+ }
+ });
+ }
+
+ private void init()
+ {
+ btnListSuppr.setOnClickListener(v -> btnListSuppr_clic());
+ txtListDate.setOnClickListener(v -> txtListDateOrImg_clic());
+ txtListIMG.setOnClickListener(v -> txtListDateOrImg_clic());
+ presenter = new HistoPresenter(vue);
+
+
+ }
+
+ private void txtListDateOrImg_clic()
+ {
+ int position = getBindingAdapterPosition();
+ presenter.transfertProfil(profils.get(position));
+ }
+ }
+}
diff --git a/app/src/main/java/com/example/coach/view/MainActivity.java b/app/src/main/java/com/example/coach/view/MainActivity.java
index 6227c8a..07fef40 100644
--- a/app/src/main/java/com/example/coach/view/MainActivity.java
+++ b/app/src/main/java/com/example/coach/view/MainActivity.java
@@ -1,13 +1,8 @@
package com.example.coach.view;
-import android.graphics.Color;
+import android.content.Intent;
import android.os.Bundle;
-import android.widget.Button;
-import android.widget.EditText;
-import android.widget.ImageView;
-import android.widget.RadioButton;
-import android.widget.TextView;
-import android.widget.Toast;
+import android.widget.ImageButton;
import androidx.activity.EdgeToEdge;
import androidx.appcompat.app.AppCompatActivity;
@@ -16,24 +11,11 @@ import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;
import com.example.coach.R;
-import com.example.coach.contract.ICalculView;
-import com.example.coach.presenter.CalculPresenter;
-/**
- * Activity qui permet le calcul de l'img
- */
-public class MainActivity extends AppCompatActivity implements ICalculView {
+public class MainActivity extends AppCompatActivity {
- private EditText txtPoids;
- private EditText txtTaille;
- private EditText txtAge;
- private RadioButton rdHomme;
- private RadioButton rdFemme;
- private TextView lblIMG;
- private ImageView imgSmiley;
- private Button btnCalc;
-
- private CalculPresenter presenter;
+ private ImageButton btnMonIMG;
+ private ImageButton btnMonHistorique;
@Override
protected void onCreate(Bundle savedInstanceState) {
@@ -43,107 +25,32 @@ public class MainActivity extends AppCompatActivity implements ICalculView {
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> {
Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);
+ init();
return insets;
});
- init();
}
- /**
- * Méthode permettant l'affichage du résultat du calcul de l'img
- * @param image nom du fichier drawable pour le smiley
- * @param img valeur de l'img
- * @param message message à afficher
- * @param normal faux si l'img n'est pas normal, vrai dans le cas inverse
- */
- @Override
- public void AfficherResultat(String image, double img, String message, boolean normal) {
- int iamgeId = getResources().getIdentifier(image, "drawable", getPackageName());
- String texte = String.format("%.01f", img) + " : IMG " + message;
-
- if(iamgeId == 0){
- imgSmiley.setImageResource(R.drawable.normal);
- }else{
- imgSmiley.setImageResource(iamgeId);
- }
- lblIMG.setText(texte);
- if(!normal){
- lblIMG.setTextColor(Color.RED);
- }else{
- lblIMG.setTextColor(Color.GREEN);
- }
- }
-
- /**
- * @param poids poids stocké
- * @param taille taille stockée
- * @param age âge stocké
- * @param sexe sexe stocké
- */
- @Override
- public void remplirChamps(Integer poids, Integer taille, Integer age, Integer sexe) {
- txtPoids.setText(poids.toString());
- txtTaille.setText(taille.toString());
- txtAge.setText(age.toString());
-
- if(sexe == 1){
- rdHomme.setChecked(true);
- }else{
- rdFemme.setChecked(false);
- }
- }
-
- /**
- * Traitements à réaliser lors du lancement de l'application
- */
private void init()
{
chargeObjetsGraphiques();
- presenter = new CalculPresenter(this);
- btnCalc.setOnClickListener(v -> btnCalcClic());
-
- presenter.chargerDernierProfil();
+ creerMenu();
}
- /**
- * Récupère les objets graphiques
- */
private void chargeObjetsGraphiques()
{
- txtPoids = (EditText) findViewById(R.id.txtPoids);
- txtTaille = (EditText) findViewById(R.id.txtTaille);
- txtAge = (EditText) findViewById(R.id.txtAge);
-
- rdHomme = (RadioButton) findViewById(R.id.rdHomme);
- rdFemme = (RadioButton) findViewById(R.id.rdFemme);
-
- lblIMG = (TextView) findViewById(R.id.lblResultat);
-
- imgSmiley = (ImageView) findViewById(R.id.imgSmiley);
-
- btnCalc = (Button) findViewById(R.id.btnCalc);
+ btnMonIMG = (ImageButton) findViewById(R.id.btnMonIMG);
+ btnMonHistorique = (ImageButton) findViewById(R.id.btnMonHistorique);
}
- /**
- * Traitements à réaliser lors du clic sur le bouton
- */
- private void btnCalcClic()
+ private void ecouteMenu(Class classe)
{
- int poids = 0, taille = 0, age = 0, sexe = 0;
+ Intent intent = new Intent(MainActivity.this, classe);
+ startActivity(intent);
+ }
- try {
- poids = Integer.parseInt(txtPoids.getText().toString());
- taille = Integer.parseInt(txtTaille.getText().toString());
- age = Integer.parseInt(txtAge.getText().toString());
- }catch (Exception ignored){}
-
- if(rdHomme.isChecked()){
- sexe = 1;
- }
-
- if(poids == 0 || taille == 0 || age == 0){
- Toast.makeText(this, "Veuillez remplir tous les champs", Toast.LENGTH_SHORT).show();
- }else{
- presenter.creerProfil(sexe, poids, taille, age);
- }
+ private void creerMenu()
+ {
+ btnMonIMG.setOnClickListener(v -> ecouteMenu(CalculActivity.class));
+ btnMonHistorique.setOnClickListener(v -> ecouteMenu(HistoActivity.class));
}
}
\ No newline at end of file
diff --git a/app/src/main/res/drawable/historique.png b/app/src/main/res/drawable/historique.png
new file mode 100644
index 0000000..0ca73be
Binary files /dev/null and b/app/src/main/res/drawable/historique.png differ
diff --git a/app/src/main/res/drawable/suppr.png b/app/src/main/res/drawable/suppr.png
new file mode 100644
index 0000000..d694412
Binary files /dev/null and b/app/src/main/res/drawable/suppr.png differ
diff --git a/app/src/main/res/layout/activity_calcul.xml b/app/src/main/res/layout/activity_calcul.xml
new file mode 100644
index 0000000..d7663a3
--- /dev/null
+++ b/app/src/main/res/layout/activity_calcul.xml
@@ -0,0 +1,173 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_histo.xml b/app/src/main/res/layout/activity_histo.xml
new file mode 100644
index 0000000..cb68f2a
--- /dev/null
+++ b/app/src/main/res/layout/activity_histo.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml
index 1f37316..9e2fff8 100644
--- a/app/src/main/res/layout/activity_main.xml
+++ b/app/src/main/res/layout/activity_main.xml
@@ -10,164 +10,64 @@
+ android:orientation="vertical">
+ android:orientation="vertical">
-
-
-
-
-
-
-
-
+ android:orientation="vertical">
-
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+ app:srcCompat="@drawable/normal" />
-
-
-
-
-
-
+ android:orientation="vertical">
+ android:gravity="center_horizontal"
+ android:text="mon historique"
+ android:textSize="34sp" />
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/layout_list_histo.xml b/app/src/main/res/layout/layout_list_histo.xml
new file mode 100644
index 0000000..900cc34
--- /dev/null
+++ b/app/src/main/res/layout/layout_list_histo.xml
@@ -0,0 +1,57 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values-night/themes.xml b/app/src/main/res/values-night/themes.xml
index df65f7d..84124d9 100644
--- a/app/src/main/res/values-night/themes.xml
+++ b/app/src/main/res/values-night/themes.xml
@@ -1,6 +1,6 @@
-
diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml
index 0e5944e..22df964 100644
--- a/app/src/main/res/values/themes.xml
+++ b/app/src/main/res/values/themes.xml
@@ -1,6 +1,6 @@
-
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index edc6a97..c15e0ff 100644
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -7,6 +7,7 @@ appcompat = "1.6.1"
material = "1.10.0"
activity = "1.8.0"
constraintlayout = "2.1.4"
+recyclerview = "1.4.0"
[libraries]
junit = { group = "junit", name = "junit", version.ref = "junit" }
@@ -16,6 +17,7 @@ appcompat = { group = "androidx.appcompat", name = "appcompat", version.ref = "a
material = { group = "com.google.android.material", name = "material", version.ref = "material" }
activity = { group = "androidx.activity", name = "activity", version.ref = "activity" }
constraintlayout = { group = "androidx.constraintlayout", name = "constraintlayout", version.ref = "constraintlayout" }
+recyclerview = { group = "androidx.recyclerview", name = "recyclerview", version.ref = "recyclerview" }
[plugins]
android-application = { id = "com.android.application", version.ref = "agp" }