initial commit

This commit is contained in:
OnlyPapy98
2025-10-28 17:31:54 +01:00
commit bd3d8a3d3f
124 changed files with 4805 additions and 0 deletions

View File

@@ -0,0 +1,27 @@
package com.example.quiz;
import com.example.quiz.data.BetsBank;
import com.example.quiz.data.repository.BetRepository;
import javax.inject.Singleton;
import dagger.Module;
import dagger.Provides;
import dagger.hilt.InstallIn;
import dagger.hilt.components.SingletonComponent;
@Module
@InstallIn(SingletonComponent.class)
public class AppModule {
@Provides
@Singleton
public BetsBank provideApiService(){
return BetsBank.getInstance();
}
@Provides
@Singleton
public BetRepository provideBetRepository() {
return new BetRepository();
}
}

View File

@@ -0,0 +1,166 @@
package com.example.quiz;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModelProvider;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.GridLayout;
import android.widget.TextView;
import android.widget.Toast;
import com.example.quiz.data.model.Horse;
import com.example.quiz.databinding.FragmentBetValidationBinding;
import com.example.quiz.utils.HPRTPrinterUtil;
import com.example.quiz.viewModel.BetViewModel;
import com.example.quiz.viewModel.SharedViewModel;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import dagger.hilt.android.AndroidEntryPoint;
/**
* A simple {@link Fragment} subclass.
* Use the {@link BetValidation#newInstance} factory method to
* create an instance of this fragment.
*/
@AndroidEntryPoint
public class BetValidation extends Fragment {
FragmentBetValidationBinding binding;
SharedViewModel shared;
BetViewModel viewModel;
private HPRTPrinterUtil printer;
private Integer id;
private String typeOfBet;
private List<Horse> selectedHorses = new ArrayList<Horse>();
private List<Horse> totalHorses;
public BetValidation() {
// Required empty public constructor
}
public static BetValidation newInstance() {
BetValidation fragment = new BetValidation();
Bundle args = new Bundle();
fragment.setArguments(args);
return fragment;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
binding = FragmentBetValidationBinding.inflate(inflater, container, false);
binding.combination.setText(getString(R.string.combination,""));
return binding.getRoot();
}
private void setupNumberGrid(GridLayout grid) {
int columns = 4;
grid.setColumnCount(columns);
if(totalHorses != null){
totalHorses.stream()
.map(this::createNumberItem)
.forEach(grid::addView);
}
}
private TextView createNumberItem(Horse horse) {
TextView textView = new TextView(requireContext());
textView.setText(String.valueOf(horse.getNumber()));
textView.setTextColor(getResources().getColor(R.color.white));
GridLayout.LayoutParams params = new GridLayout.LayoutParams();
params.setMargins(10, 10, 10, 10);
textView.setLayoutParams(params);
textView.setTextSize(21);
textView.setWidth(130);
textView.setHeight(130);
textView.setGravity(Gravity.CENTER);
textView.setBackgroundResource(R.drawable.number_background);
textView.setTextAlignment(View.TEXT_ALIGNMENT_CENTER);
textView.setOnClickListener(v -> {
if (selectedHorses.contains(horse)) {
selectedHorses.remove(horse);
v.setSelected(false);
v.setBackgroundResource(R.drawable.number_background);
} else {
selectedHorses.add(horse);
v.setSelected(true);
v.setBackgroundResource(R.drawable.number_selected_background);
}
String combinationText = selectedHorses.stream()
.map(h -> String.valueOf(h.getNumber()))
.collect(Collectors.joining("-"));
binding.combination.setText(getString(R.string.combination, combinationText));
});
return textView;
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
shared = new ViewModelProvider(requireActivity()).get(SharedViewModel.class);
viewModel = new ViewModelProvider(this).get(BetViewModel.class);
shared.betId.observe(getViewLifecycleOwner(), id ->{
this.id = id;
viewModel.getBetNameById(id - 1);
viewModel.betName.observe(getViewLifecycleOwner(), name ->{
binding.horseName.setText(name);
});
viewModel.loadHorses(id - 1);
viewModel.horses.observe(getViewLifecycleOwner(), h->{
this.totalHorses = h;
setupNumberGrid(binding.gridNumbers);
});
});
shared.typeOfBet.observe(getViewLifecycleOwner(), type ->{
this.typeOfBet = type;
});
binding.btnValidate.setOnClickListener(v->{
//Toast.makeText(getContext(), "L'id de bet: "+this.id+" et le type est: "+this.typeOfBet, Toast.LENGTH_SHORT).show();
printer = new HPRTPrinterUtil(getContext());
boolean ok = printer.connectBluetooth("02:03:00:00:00:00");
if (ok) {
printer.printText("Bonjour");
}
});
}
@Override
public void onDestroyView() {
super.onDestroyView();
binding = null;
}
}

View File

@@ -0,0 +1,44 @@
package com.example.quiz;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.navigation.fragment.NavHostFragment;
import com.example.quiz.databinding.FragmentFirst2Binding;
public class First2Fragment extends Fragment {
private FragmentFirst2Binding binding;
@Override
public View onCreateView(
@NonNull LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState
) {
binding = FragmentFirst2Binding.inflate(inflater, container, false);
return binding.getRoot();
}
public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
binding.buttonFirst.setOnClickListener(v ->
NavHostFragment.findNavController(First2Fragment.this)
.navigate(R.id.action_First2Fragment_to_Second2Fragment)
);
}
@Override
public void onDestroyView() {
super.onDestroyView();
binding = null;
}
}

View File

@@ -0,0 +1,44 @@
package com.example.quiz;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.navigation.fragment.NavHostFragment;
import com.example.quiz.databinding.FragmentFirstBinding;
public class FirstFragment extends Fragment {
private FragmentFirstBinding binding;
@Override
public View onCreateView(
@NonNull LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState
) {
binding = FragmentFirstBinding.inflate(inflater, container, false);
return binding.getRoot();
}
public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
binding.buttonFirst.setOnClickListener(v ->
NavHostFragment.findNavController(FirstFragment.this)
.navigate(R.id.action_FirstFragment_to_SecondFragment)
);
}
@Override
public void onDestroyView() {
super.onDestroyView();
binding = null;
}
}

View File

@@ -0,0 +1,127 @@
package com.example.quiz;
import android.annotation.SuppressLint;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.core.app.ActivityCompat;
import androidx.core.app.ComponentActivity;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.LinearLayoutManager;
import android.service.controls.Control;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.view.animation.LayoutAnimationController;
import android.widget.Toast;
import com.example.quiz.data.adapter.BetsAdapter;
import com.example.quiz.databinding.FragmentListOFBettingBinding;
import com.example.quiz.viewModel.BetViewModel;
import com.example.quiz.viewModel.SharedViewModel;
import dagger.hilt.android.AndroidEntryPoint;
import dagger.hilt.android.internal.lifecycle.HiltViewModelFactory;
/**
* A simple {@link Fragment} subclass.
* Use the {@link ListOFBets#newInstance} factory method to
* create an instance of this fragment.
*/
@AndroidEntryPoint
public class ListOFBets extends Fragment {
private String username;
private View view;
FragmentListOFBettingBinding binding;
private BetViewModel viewModel;
private SharedViewModel shared;
private BetsAdapter adapter;
private AppCompatActivity activity;
public static ListOFBets newInstance(String username) {
ListOFBets fragment = new ListOFBets();
Bundle args = new Bundle();
args.putString("ARG_USERNAME", username);
fragment.setArguments(args);
return fragment;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if(getArguments() != null){
username = getArguments().getString("ARG_USERNAME");
}
}
@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
binding = FragmentListOFBettingBinding.inflate(inflater, container, false);
activity = (AppCompatActivity) getActivity();
if(activity != null){
if(activity.getSupportActionBar() != null){
activity.getSupportActionBar().show();
activity.getSupportActionBar().setTitle("Liste des paris");
}
}
adapter = new BetsAdapter();
binding.recyclerView.setLayoutManager(new GridLayoutManager(getContext(), 2));
binding.recyclerView.setAdapter(adapter);
LayoutAnimationController controller = AnimationUtils.loadLayoutAnimation(getContext(), R.anim.layout_fad_in);
binding.recyclerView.setLayoutAnimation(controller);
viewModel = new ViewModelProvider(this).get(BetViewModel.class);
shared = new ViewModelProvider(requireActivity()).get(SharedViewModel.class);
viewModel.bets.observe(getViewLifecycleOwner(), bets -> {
adapter.setBets(bets);
adapter.setOnItemClickListener(position -> {
shared.setBetId(position);
FragmentManager fragmentManager = getParentFragmentManager();
ListOfTypeOfBets typeOfBets = ListOfTypeOfBets.newInstance();
fragmentManager.beginTransaction()
.replace(R.id.nav_host_fragment_content_main, typeOfBets)
.addToBackStack(null)
.commit();
});
});
viewModel.loadBets();
return binding.getRoot();
}
@SuppressLint("UseSupportActionBar")
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
AppCompatActivity activity = (AppCompatActivity) getActivity();
if(activity!=null){
Toolbar toolbar = activity.findViewById(R.id.toolbar);
toolbar.setBackgroundColor(getResources().getColor(R.color.primary_green));
toolbar.setTitleTextColor(getResources().getColor(R.color.text_light_grey));
activity.setSupportActionBar(toolbar);
if(activity.getSupportActionBar() != null){
activity.getSupportActionBar().setTitle(username);
}
}
}
}

View File

@@ -0,0 +1,84 @@
package com.example.quiz;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.lifecycle.ViewModelProvider;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.Toast;
import com.example.quiz.databinding.FragmentListOfTypeOfBetsBinding;
import com.example.quiz.viewModel.SharedViewModel;
import dagger.hilt.android.AndroidEntryPoint;
/**
* A simple {@link Fragment} subclass.
* Use the {@link ListOfTypeOfBets#newInstance} factory method to
* create an instance of this fragment.
*/
@AndroidEntryPoint
public class ListOfTypeOfBets extends Fragment {
private FragmentListOfTypeOfBetsBinding binding;
private SharedViewModel shared;
public ListOfTypeOfBets() {
// Required empty public constructor
}
public static ListOfTypeOfBets newInstance() {
ListOfTypeOfBets fragment = new ListOfTypeOfBets();
Bundle args = new Bundle();
fragment.setArguments(args);
return fragment;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
binding = FragmentListOfTypeOfBetsBinding.inflate(inflater, container, false);
return binding.getRoot();
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
RadioGroup types = binding.optionsGroup;
Button btnValidate = binding.btnValidate;
btnValidate.setOnClickListener(v->{
int selectedId = types.getCheckedRadioButtonId();
if (selectedId == -1) {
Toast.makeText(requireContext(), "Veuillez sélectionner une option", Toast.LENGTH_SHORT).show();
return;
}
RadioButton selectedButton = view.findViewById(selectedId);
String selectedType = selectedButton.getText().toString();
shared = new ViewModelProvider(requireActivity()).get(SharedViewModel.class);
shared.setTypeOfBet(selectedType);
FragmentManager fragmentManager = getParentFragmentManager();
BetValidation betValidation = BetValidation.newInstance();
fragmentManager.beginTransaction()
.replace(R.id.nav_host_fragment_content_main, betValidation)
.addToBackStack(null)
.commit();
});
}
}

View File

@@ -0,0 +1,106 @@
package com.example.quiz;
import android.app.Activity;
import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.content.ContextCompat;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;
import android.widget.Toolbar;
import com.example.quiz.databinding.FragmentLoginBinding;
import com.example.quiz.utils.SharedPrefsHelper;
/**
* A simple {@link Fragment} subclass.
* Use the {@link Login#newInstance} factory method to
* create an instance of this fragment.
*/
public class Login extends Fragment {
private SharedPrefsHelper prefsHelper;
public Login() {
// Required empty public constructor
}
public static Login newInstance() {
Login fragment = new Login();
Bundle args = new Bundle();
fragment.setArguments(args);
return fragment;
}
private FragmentLoginBinding binding;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
binding = FragmentLoginBinding.inflate(inflater, container, false);
return binding.getRoot();
}
@Override
public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
AppCompatActivity activity = (AppCompatActivity) getActivity();
if(activity != null){
activity.getSupportActionBar().hide();
}
}
public void onStart(){
super.onStart();
binding.loginButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(binding.userNameInput.getText().toString().isEmpty()){
binding.userNameInput.setError("Le nom d'utilisateur est obligatoire");
binding.userNameInput.requestFocus();
return;
}
if(binding.passwordInput.getText().toString().isEmpty()){
binding.passwordInput.setError("Le mot de passe est obligatoire");
binding.passwordInput.requestFocus();
return;
}
if(binding.passwordInput.getText().toString().length() < 6){
binding.passwordInput.setError("Le mot de passe doit contenir au moins 6 caractères ");
binding.passwordInput.requestFocus();
return;
}
prefsHelper = SharedPrefsHelper.getInstance(getContext());
prefsHelper.save("username", binding.userNameInput.getText().toString());
FragmentManager fragmentManager = getParentFragmentManager();
ListOFBets bets = ListOFBets.newInstance(binding.userNameInput.getText().toString());
fragmentManager.beginTransaction()
.replace(R.id.nav_host_fragment_content_main, bets)
.commit();
}
});
}
@Override
public void onDestroyView() {
super.onDestroyView();
binding = null;
}
}

View File

@@ -0,0 +1,57 @@
package com.example.quiz;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;
public class MapsFragment extends Fragment {
private OnMapReadyCallback callback = new OnMapReadyCallback() {
/**
* Manipulates the map once available.
* This callback is triggered when the map is ready to be used.
* This is where we can add markers or lines, add listeners or move the camera.
* In this case, we just add a marker near Sydney, Australia.
* If Google Play services is not installed on the device, the user will be prompted to
* install it inside the SupportMapFragment. This method will only be triggered once the
* user has installed Google Play services and returned to the app.
*/
@Override
public void onMapReady(GoogleMap googleMap) {
LatLng sydney = new LatLng(-34, 151);
googleMap.addMarker(new MarkerOptions().position(sydney).title("Marker in Sydney"));
googleMap.moveCamera(CameraUpdateFactory.newLatLng(sydney));
}
};
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater,
@Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_maps, container, false);
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
SupportMapFragment mapFragment =
(SupportMapFragment) getChildFragmentManager().findFragmentById(R.id.map);
if (mapFragment != null) {
mapFragment.getMapAsync(callback);
}
}
}

View File

@@ -0,0 +1,71 @@
package com.example.quiz;
import android.graphics.Color;
import android.os.Bundle;
import com.example.quiz.utils.SharedPrefsHelper;
import com.google.android.material.snackbar.Snackbar;
import androidx.appcompat.app.AppCompatActivity;
import android.view.View;
import androidx.fragment.app.FragmentManager;
import androidx.navigation.NavController;
import androidx.navigation.Navigation;
import androidx.navigation.ui.AppBarConfiguration;
import androidx.navigation.ui.NavigationUI;
import com.example.quiz.databinding.ActivityPageQuizBinding;
import dagger.hilt.android.AndroidEntryPoint;
@AndroidEntryPoint
public class PageQuiz extends AppCompatActivity {
private AppBarConfiguration appBarConfiguration;
private ActivityPageQuizBinding binding;
private SharedPrefsHelper prefsHelper;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = ActivityPageQuizBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
setSupportActionBar(binding.toolbar);
binding.toolbar.setBackgroundColor(Color.parseColor("#501C5A29"));
binding.fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAnchorView(R.id.fab)
.setAction("Action", null).show();
}
});
prefsHelper = SharedPrefsHelper.getInstance(getApplicationContext());
FragmentManager fragmentManager = getSupportFragmentManager();
if(prefsHelper.get("username") != null){
ListOFBets bets = ListOFBets.newInstance(prefsHelper.get("username"));
fragmentManager
.beginTransaction()
.replace(R.id.nav_host_fragment_content_main, bets)
.commit();
}else{
Login login = Login.newInstance();
fragmentManager
.beginTransaction()
.replace(R.id.nav_host_fragment_content_main, login)
.commit();
}
}
@Override
public boolean onSupportNavigateUp() {
NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment_content_page_quiz);
return NavigationUI.navigateUp(navController, appBarConfiguration)
|| super.onSupportNavigateUp();
}
}

View File

@@ -0,0 +1,11 @@
package com.example.quiz;
import android.app.Application;
import com.example.quiz.utils.SharedPrefsHelper;
import dagger.hilt.android.HiltAndroidApp;
@HiltAndroidApp
public class PmuHorseBetting extends Application {
}

View File

@@ -0,0 +1,80 @@
package com.example.quiz;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.example.quiz.data.model.Question;
import com.example.quiz.databinding.FragmentQuestionsBinding;
import com.example.quiz.injection.QuestionViewModelFactory;
import com.example.quiz.viewModel.QuestionViewModel;
public class Questions extends Fragment {
private FragmentQuestionsBinding binding;
private QuestionViewModel viewModel;
public Questions() {
// Required empty public constructor
}
public static Questions newInstance(String username) {
Questions fragment = new Questions();
Bundle args = new Bundle();
args.putString("ARG_USERNAME", username);
fragment.setArguments(args);
return fragment;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
viewModel = new ViewModelProvider(this, QuestionViewModelFactory.getInstance()).get(QuestionViewModel.class);
}
@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
binding = FragmentQuestionsBinding.inflate(inflater, container, false);
// Inflate the layout for this fragment
return binding.getRoot();
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
viewModel.startQuiz();
viewModel.currentQuestion.observe(getViewLifecycleOwner(), new Observer<Question>() {
@Override
public void onChanged(Question question) {
binding.questionText.setText(question.getQuestion());
binding.answer1.setText(question.getAnswers().get(0));
binding.answer2.setText(question.getAnswers().get(1));
binding.answer3.setText(question.getAnswers().get(2));
binding.answer4.setText(question.getAnswers().get(3));
}
});
}
@Override
public void onStart() {
super.onStart();
binding.nextButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
viewModel.nextQuestion();
}
});
}
}

View File

@@ -0,0 +1,44 @@
package com.example.quiz;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.navigation.fragment.NavHostFragment;
import com.example.quiz.databinding.FragmentSecond2Binding;
public class Second2Fragment extends Fragment {
private FragmentSecond2Binding binding;
@Override
public View onCreateView(
@NonNull LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState
) {
binding = FragmentSecond2Binding.inflate(inflater, container, false);
return binding.getRoot();
}
public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
binding.buttonSecond.setOnClickListener(v ->
NavHostFragment.findNavController(Second2Fragment.this)
.navigate(R.id.action_Second2Fragment_to_First2Fragment)
);
}
@Override
public void onDestroyView() {
super.onDestroyView();
binding = null;
}
}

View File

@@ -0,0 +1,44 @@
package com.example.quiz;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.navigation.fragment.NavHostFragment;
import com.example.quiz.databinding.FragmentSecondBinding;
public class SecondFragment extends Fragment {
private FragmentSecondBinding binding;
@Override
public View onCreateView(
@NonNull LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState
) {
binding = FragmentSecondBinding.inflate(inflater, container, false);
return binding.getRoot();
}
public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
binding.buttonSecond.setOnClickListener(v ->
NavHostFragment.findNavController(SecondFragment.this)
.navigate(R.id.action_SecondFragment_to_FirstFragment)
);
}
@Override
public void onDestroyView() {
super.onDestroyView();
binding = null;
}
}

View File

@@ -0,0 +1,72 @@
package com.example.quiz.data;
import com.example.quiz.data.model.Bet;
import com.example.quiz.data.model.Horse;
import java.time.LocalDate;
import java.util.Arrays;
import java.util.List;
public class BetsBank {
public List<Bet> getBet() {
return Arrays.asList(
new Bet(
1,
"Course de chevaux",
LocalDate.of(2025,10,1),
Arrays.asList(
new Horse(1),
new Horse(2),
new Horse(3),
new Horse(4)
)
),
new Bet(
2,
"Course de chevaux 2",
LocalDate.of(2025,10,1),
Arrays.asList(
new Horse(4),
new Horse(5),
new Horse(7),
new Horse(6)
)
),
new Bet(
3,
"Course de chevaux 3",
LocalDate.of(2025,10,1),
Arrays.asList(
new Horse(10),
new Horse(90),
new Horse(45),
new Horse(9)
)
),
new Bet(
4,
"Course de chevaux 4",
LocalDate.of(2025,10,1),
Arrays.asList(
new Horse(5),
new Horse(33),
new Horse(26),
new Horse(99),
new Horse(100),
new Horse(101),
new Horse(102),
new Horse(103),
new Horse(104),
new Horse(105)
)
)
);
}
public static BetsBank instance;
public static BetsBank getInstance(){
if(instance == null){
instance = new BetsBank();
}
return instance;
}
}

View File

@@ -0,0 +1,69 @@
package com.example.quiz.data;
import com.example.quiz.data.model.Question;
import java.util.Arrays;
import java.util.List;
public class QuestionsBank {
public List<Question> getQuestions() {
return Arrays.asList(
new Question(
"Who is the creator of Android?",
Arrays.asList(
"Andy Rubin",
"Steve Wozniak",
"Jake Wharton",
"Paul Smith"
),
0
),
new Question(
"When did the first man land on the moon?",
Arrays.asList(
"1958",
"1962",
"1967",
"1969"
),
3
),
new Question(
"What is the house number of The Simpsons?",
Arrays.asList(
"42",
"101",
"666",
"742"
),
3
),
new Question(
"Who painteddid the Mona Lisa paint?",
Arrays.asList(
"Michelangelo",
"Leonardo Da Vinci",
"Raphael",
"Caravaggio"
),
1
),
new Question(
"What is the country top-level domain of Belgium?",
Arrays.asList(
".bg",
".bm",
".bl",
".be"
),
3
)
);
}
private static QuestionsBank instance;
public static QuestionsBank getInstance() {
if (instance == null) {
instance = new QuestionsBank();
}
return instance;
}
}

View File

@@ -0,0 +1,75 @@
package com.example.quiz.data.adapter;
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.quiz.R;
import com.example.quiz.data.model.Bet;
import java.util.ArrayList;
import java.util.List;
public class BetsAdapter extends RecyclerView.Adapter<BetsAdapter.BetViewHolder> {
private List<Bet> bets = new ArrayList<>();
private onItemClickListener listener;
public interface onItemClickListener {
void onItemClick(int position);
}
public void setOnItemClickListener(onItemClickListener listener){
this.listener = listener;
}
public void setBets(List<Bet> bets){
this.bets = bets;
notifyDataSetChanged();
}
@NonNull
@Override
public BetViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_bet, parent, false);
return new BetViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull BetViewHolder holder, int position) {
Bet bet = bets.get(position);
holder.tvDate.setText(String.valueOf(bet.getDate()));
holder.tvName.setText(String.valueOf(bet.getName()));
holder.itemView.setOnClickListener(v->{
if(listener != null){
listener.onItemClick(bet.getId());
}
});
}
@Override
public int getItemCount(){
return bets.size();
}
static class BetViewHolder extends RecyclerView.ViewHolder{
TextView tvName, tvDate;
public BetViewHolder(@NonNull View itemView) {
super(itemView);
tvName = itemView.findViewById(R.id.tvName);
tvDate = itemView.findViewById(R.id.tvDate);
}
}
}

View File

@@ -0,0 +1,52 @@
package com.example.quiz.data.model;
import java.time.LocalDate;
import java.util.List;
public class Bet {
private int id;
private String name;
private LocalDate date;
private List<Horse> horses;
public List<Horse> getHorses() {
return horses;
}
public void setHorses(List<Horse> horses) {
this.horses = horses;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public LocalDate getDate() {
return date;
}
public void setDate(LocalDate date) {
this.date = date;
}
public Bet(int id, String name, LocalDate date, List<Horse> horses) {
this.id = id;
this.name = name;
this.date = date;
this.horses = horses;
}
}

View File

@@ -0,0 +1,18 @@
package com.example.quiz.data.model;
public class Horse {
private Integer number;
public Horse(Integer number) {
this.number = number;
}
public Integer getNumber() {
return number;
}
public void setNumber(Integer number) {
this.number = number;
}
}

View File

@@ -0,0 +1,39 @@
package com.example.quiz.data.model;
import java.util.List;
public class Question {
private String question;
private List<String> answers;
private Integer indexAnswer;
public Question(String question, List<String> answers, int indexAnswer){
this.question = question;
this.answers = answers;
this.indexAnswer = indexAnswer;
}
public int getIndexAnswer() {
return indexAnswer;
}
public void setIndexAnswer(int indexAnswer) {
this.indexAnswer = indexAnswer;
}
public String getQuestion() {
return question;
}
public void setQuestion(String question) {
this.question = question;
}
public List<String> getAnswers() {
return answers;
}
public void setAnswers(List<String> answers) {
this.answers = answers;
}
}

View File

@@ -0,0 +1,46 @@
package com.example.quiz.data.repository;
import com.example.quiz.data.BetsBank;
import com.example.quiz.data.model.Bet;
import com.example.quiz.data.model.Horse;
import java.util.List;
import javax.inject.Inject;
import javax.inject.Singleton;
@Singleton
public class BetRepository {
private BetsBank betsBank;
@Inject
public BetRepository(BetsBank betsBank){
this.betsBank = betsBank;
}
public BetRepository(){
this.betsBank = BetsBank.getInstance();
}
public List<Bet> getAllBets(){
return betsBank.getBet();
}
public Bet getBetById(int id){
return betsBank.getBet().get(id);
}
public List<Horse> getHorsesById(int id){
return getBetById(id).getHorses();
}
public BetRepository getInstance(){
return new BetRepository();
}
public String getBetNameById(int id){
return getBetById(id).getName();
}
}

View File

@@ -0,0 +1,31 @@
package com.example.quiz.data.repository;
import com.example.quiz.data.QuestionsBank;
import com.example.quiz.data.model.Question;
import java.util.List;
import java.util.Map;
public class QuestionRepository {
private QuestionsBank questionsBank;
public QuestionRepository(){
this.questionsBank = QuestionsBank.getInstance();
}
public List<Question> getQuestions(){
return questionsBank.getQuestions();
}
public Object updateQuestionById(int id, Question question){
Question myQuestion = questionsBank.getQuestions().get(id);
if(question == null) return Map.of("error", "Cette question n'existe pas!");
myQuestion.setQuestion(question.getQuestion()!=null?question.getQuestion():myQuestion.getQuestion());
myQuestion.setAnswers(!question.getAnswers().isEmpty()?question.getAnswers():myQuestion.getAnswers());
myQuestion.setIndexAnswer(question.getIndexAnswer() > 3?question.getIndexAnswer():myQuestion.getIndexAnswer());
return Map.of("success", true);
}
public QuestionRepository getInstance(){
return new QuestionRepository();
}
}

View File

@@ -0,0 +1,38 @@
package com.example.quiz.injection;
import androidx.annotation.NonNull;
import androidx.lifecycle.ViewModel;
import androidx.lifecycle.ViewModelProvider;
import com.example.quiz.data.repository.QuestionRepository;
import com.example.quiz.viewModel.QuestionViewModel;
public class QuestionViewModelFactory implements ViewModelProvider.Factory {
private QuestionRepository questionRepository;
private static QuestionViewModelFactory factory;
public static QuestionViewModelFactory getInstance(){
if(factory == null){
synchronized (QuestionViewModel.class){
if(factory == null){
factory = new QuestionViewModelFactory();
}
}
}
return factory;
}
private QuestionViewModelFactory(){
this.questionRepository = new QuestionRepository();
}
@Override
@NonNull
public <T extends ViewModel> T create(@NonNull Class<T> modelClass){
if(modelClass.isAssignableFrom(QuestionViewModel.class)){
return (T) new QuestionViewModel(questionRepository);
}
throw new IllegalArgumentException("Unknown ViewModel class");
}
}

View File

@@ -0,0 +1,91 @@
package com.example.quiz.utils;
import android.content.Context;
import android.util.Log;
import android.widget.Toast;
import tspl.HPRTPrinterHelper;
public class HPRTPrinterUtil {
private static final String TAG = "HPRTPrinterUtil";
private Context context;
public HPRTPrinterUtil(Context context) {
this.context = context;
}
/**
* Connecte une imprimante Bluetooth
* @param btAddress adresse MAC Bluetooth de l'imprimante
* @return true si connecté, false sinon
*/
public boolean connectBluetooth(String btAddress) {
try {
HPRTPrinterHelper.PortClose(); // ferme toute connexion existante
int result = HPRTPrinterHelper.PortOpen("Bluetooth," + btAddress);
if (result == 0) {
Log.d(TAG, "Connexion réussie");
Toast.makeText(context, "Imprimante connectée", Toast.LENGTH_SHORT).show();
return true;
} else {
Log.e(TAG, "Erreur connexion: " + result);
Toast.makeText(context, "Erreur connexion imprimante: " + result, Toast.LENGTH_SHORT).show();
return false;
}
} catch (Exception e) {
Log.e(TAG, "Erreur connexion: " + e.getMessage());
return false;
}
}
public void printText(String text) {
try {
if (!HPRTPrinterHelper.IsOpened()) {
Toast.makeText(context, "Imprimante non connectée", Toast.LENGTH_SHORT).show();
return;
}
// TSPL pur pour texte simple
String tspl = ""+ text + "\r\n";
// Envoi à l'imprimante
HPRTPrinterHelper.PrintData(tspl);
Log.d(TAG, "Texte imprimé sur ticket"); // on log seulement le succès
} catch (Exception e) {
Log.e(TAG, "Erreur impression TSPL: " + e.getMessage());
Toast.makeText(context, "Erreur impression TSPL", Toast.LENGTH_SHORT).show();
}
}
public void printTSPLTemplate(String tsplTemplate) {
try {
if (!HPRTPrinterHelper.IsOpened()) {
Toast.makeText(context, "Imprimante non connectée", Toast.LENGTH_SHORT).show();
return;
}
HPRTPrinterHelper.PrintData(tsplTemplate);
Log.d(TAG, "Template imprimé");
} catch (Exception e) {
Log.e(TAG, "Erreur impression TSPL: " + e.getMessage());
Toast.makeText(context, "Erreur impression TSPL", Toast.LENGTH_SHORT).show();
}
}
/**
* Déconnecte l'imprimante
*/
public void disconnect() {
try {
HPRTPrinterHelper.PortClose();
Toast.makeText(context, "Imprimante déconnectée", Toast.LENGTH_SHORT).show();
} catch (Exception e) {
Log.e(TAG, "Erreur déconnexion: " + e.getMessage());
}
}
}

View File

@@ -0,0 +1,34 @@
package com.example.quiz.utils;
import android.content.Context;
import android.content.SharedPreferences;
public class SharedPrefsHelper {
private static final String PREF_NAME = "quiz_prefs";
private static SharedPrefsHelper instance;
private SharedPreferences prefs;
private SharedPrefsHelper(Context context) {
prefs = context.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE);
}
public static SharedPrefsHelper getInstance(Context context) {
if (instance == null) {
instance = new SharedPrefsHelper(context.getApplicationContext());
}
return instance;
}
public void save(String key, String value) {
prefs.edit().putString(key, value).apply();
}
public String get(String key) {
return prefs.getString(key, null);
}
public void clear() {
prefs.edit().clear().apply();
}
}

View File

@@ -0,0 +1,46 @@
package com.example.quiz.viewModel;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;
import com.example.quiz.data.model.Bet;
import com.example.quiz.data.model.Horse;
import com.example.quiz.data.repository.BetRepository;
import java.util.List;
import javax.inject.Inject;
import dagger.hilt.android.lifecycle.HiltViewModel;
@HiltViewModel
public class BetViewModel extends ViewModel {
private BetRepository betRepository;
public MutableLiveData<List<Bet>> bets = new MutableLiveData<List<Bet>>();
public MutableLiveData<String> betName = new MutableLiveData<String>();
public MutableLiveData<List<Horse>> horses = new MutableLiveData<>();
@Inject
public BetViewModel(BetRepository betRepository){
this.betRepository = betRepository;
}
public void loadBets(){
bets.setValue(betRepository.getAllBets());
}
public void loadHorses(int id){
horses.setValue(betRepository.getHorsesById(id));
}
public void getBetNameById(int id){
betName.setValue(betRepository.getBetNameById(id));
}
}

View File

@@ -0,0 +1,41 @@
package com.example.quiz.viewModel;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;
import com.example.quiz.data.model.Question;
import com.example.quiz.data.repository.QuestionRepository;
import java.util.Objects;
public class QuestionViewModel extends ViewModel {
private QuestionRepository questionRepository;
public MutableLiveData<Question> currentQuestion = new MutableLiveData<Question>();
public MutableLiveData<Integer> score = new MutableLiveData<Integer>();
public MutableLiveData<Boolean> isLastQuestion = new MutableLiveData<Boolean>(false);
public QuestionViewModel(QuestionRepository questionRepository){
this.questionRepository = questionRepository;
}
public void startQuiz(){
currentQuestion.setValue(questionRepository.getQuestions().get(0));
score.setValue(0);
}
public Boolean isAnswerValid(int answerIndex){
return answerIndex == Objects.requireNonNull(currentQuestion.getValue()).getIndexAnswer();
}
public void nextQuestion(){
int currentQuestionIndex = questionRepository.getQuestions().indexOf(currentQuestion.getValue());
if(currentQuestionIndex == questionRepository.getQuestions().size()-1){
isLastQuestion.setValue(true);
}else{
currentQuestion.setValue(questionRepository.getQuestions().get(currentQuestionIndex+1));
}
}
}

View File

@@ -0,0 +1,22 @@
package com.example.quiz.viewModel;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;
import javax.inject.Inject;
import dagger.hilt.android.lifecycle.HiltViewModel;
public class SharedViewModel extends ViewModel {
public MutableLiveData<Integer> betId = new MutableLiveData<Integer>();
public MutableLiveData<String> typeOfBet = new MutableLiveData<String>();
public void setBetId(int id){
betId.setValue(id);
}
public void setTypeOfBet(String type){
typeOfBet.setValue(type);
}
}