diff --git a/.idea/.gitignore b/.idea/.gitignore
new file mode 100644
index 0000000..26d3352
--- /dev/null
+++ b/.idea/.gitignore
@@ -0,0 +1,3 @@
+# Default ignored files
+/shelf/
+/workspace.xml
diff --git a/app/src/main/java/fr/uca/iut/myouafff/ui/activity/DogActivity.kt b/app/src/main/java/fr/uca/iut/myouafff/ui/activity/DogActivity.kt
index c67b0e7..64a394a 100644
--- a/app/src/main/java/fr/uca/iut/myouafff/ui/activity/DogActivity.kt
+++ b/app/src/main/java/fr/uca/iut/myouafff/ui/activity/DogActivity.kt
@@ -5,6 +5,7 @@ import android.content.Intent
import android.os.Bundle
import fr.uca.iut.myouafff.R
import fr.uca.iut.myouafff.data.NEW_DOG_ID
+import fr.uca.iut.myouafff.ui.fragment.DogFragment
class DogActivity : SimpleFragmentActivity(), DogFragment.OnInteractionListener {
diff --git a/app/src/main/java/fr/uca/iut/myouafff/ui/dialog/DatePickerFragment.kt b/app/src/main/java/fr/uca/iut/myouafff/ui/dialog/DatePickerFragment.kt
new file mode 100644
index 0000000..c0f0231
--- /dev/null
+++ b/app/src/main/java/fr/uca/iut/myouafff/ui/dialog/DatePickerFragment.kt
@@ -0,0 +1,59 @@
+package fr.uca.iut.myouafff.ui.dialog
+
+import android.app.Dialog
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.widget.DatePicker
+import androidx.appcompat.app.AlertDialog
+import androidx.appcompat.app.AppCompatDialogFragment
+import androidx.core.os.bundleOf
+import androidx.fragment.app.setFragmentResult
+import fr.uca.iut.myouafff.R
+import java.util.*
+
+class DatePickerFragment : AppCompatDialogFragment() {
+ companion object {
+ const val EXTRA_YEAR = "fr.iut.uca.myouafff.year"
+ const val EXTRA_MONTH = "fr.iut.uca.myouafff.month"
+ const val EXTRA_DAY = "fr.iut.uca.myouafff.day"
+
+ private const val ARG_DATE = "date"
+
+ fun newInstance(requestKey: String, date: Date? = null) = DatePickerFragment().apply {
+ this.requestKey = requestKey
+ if (date != null)
+ arguments = Bundle().apply {
+ putLong(ARG_DATE, date.time)
+ }
+ }
+ }
+
+ private lateinit var requestKey: String
+
+ override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
+ val view = LayoutInflater.from(activity).inflate(R.layout.dialog_date, null)
+ val calendar = Calendar.getInstance()
+ calendar.timeInMillis = arguments?.getLong(ARG_DATE) ?: Date().time
+ val year = calendar.get(Calendar.YEAR)
+ val month = calendar.get(Calendar.MONTH)
+ val day = calendar.get(Calendar.DAY_OF_MONTH)
+
+ val datePicker = view as DatePicker
+ datePicker.init(year, month, day, null)
+
+ return AlertDialog.Builder(view.context, R.style.NarrowDialog)
+ .setView(view)
+ .setPositiveButton(android.R.string.ok) { _, _ ->
+ setFragmentResult(
+ requestKey,
+ bundleOf(
+ EXTRA_YEAR to datePicker.year,
+ EXTRA_MONTH to datePicker.month,
+ EXTRA_DAY to datePicker.dayOfMonth
+ )
+ )
+ }
+ .setNegativeButton(android.R.string.cancel, null)
+ .create()
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/fr/uca/iut/myouafff/ui/fragment/DogFragment.kt b/app/src/main/java/fr/uca/iut/myouafff/ui/fragment/DogFragment.kt
index 2875bae..94a4652 100644
--- a/app/src/main/java/fr/uca/iut/myouafff/ui/fragment/DogFragment.kt
+++ b/app/src/main/java/fr/uca/iut/myouafff/ui/fragment/DogFragment.kt
@@ -1,21 +1,35 @@
package fr.uca.iut.myouafff.ui.fragment
+import android.app.AlertDialog
+import android.content.Context
import android.os.Bundle
-import android.widget.DatePicker
+import android.provider.ContactsContract
+import android.text.format.DateFormat
+import android.view.*
import android.widget.EditText
import android.widget.RatingBar
import android.widget.Spinner
import android.widget.TextView
+import androidx.activity.result.contract.ActivityResultContracts
+import androidx.activity.result.launch
import androidx.core.os.bundleOf
+import androidx.core.view.MenuProvider
import androidx.fragment.app.Fragment
import androidx.fragment.app.setFragmentResultListener
+import androidx.lifecycle.Lifecycle
+import fr.uca.iut.myouafff.R
import fr.uca.iut.myouafff.data.Dog
import fr.uca.iut.myouafff.data.NEW_DOG_ID
+import fr.uca.iut.myouafff.data.persistence.DogDatabase
+import fr.uca.iut.myouafff.data.persistence.converter.toGender
+import fr.uca.iut.myouafff.ui.dialog.DatePickerFragment
+import java.util.Date
+import java.util.Calendar
class DogFragment : Fragment() {
companion object {
- private const val EXTRA_DOG_ID = "fr.iut.ouafff.extra_dogid"
+ private const val EXTRA_DOG_ID = "fr.uca.iut.myouafff.extra_dogid"
private const val REQUEST_DATE = "DateRequest"
private const val DIALOG_DATE = "DateDialog"
@@ -24,7 +38,7 @@ class DogFragment : Fragment() {
}
}
- private lateinit var dog : Dog
+ private lateinit var dog: Dog
private var dogId: Long = NEW_DOG_ID
private lateinit var dogNameEditor: EditText
@@ -35,15 +49,187 @@ class DogFragment : Fragment() {
private lateinit var dogOwnerText: TextView
private lateinit var dogAdmissionDateText: TextView
+ private val pickOwner =
+ registerForActivityResult(ActivityResultContracts.PickContact()) { contactUri ->
+ if (contactUri != null) {
+ val queryFields = arrayOf(ContactsContract.Contacts.DISPLAY_NAME)
+ val contactCursor = activity?.contentResolver?.query(
+ contactUri, queryFields, null, null, null
+ )
+
+ contactCursor?.let {
+ if (it.count != 0) {
+ it.moveToFirst()
+ dog.owner = it.getString(0)
+ }
+ it.close()
+ }
+ dogOwnerText.text = dog.owner
+ }
+ }
+
+ interface OnInteractionListener {
+ fun onDogSaved()
+ fun onDogDeleted()
+ }
+
+ private var listener: OnInteractionListener? = null
+
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setFragmentResultListener(REQUEST_DATE, this::onAdmissionDateChanged)
+
+ dogId = savedInstanceState?.getLong(EXTRA_DOG_ID) ?: arguments?.getLong(EXTRA_DOG_ID)
+ ?: NEW_DOG_ID
+
+ dog = if (dogId == NEW_DOG_ID) {
+ requireActivity().setTitle(R.string.title_add_dog)
+ Dog()
+ } else {
+ DogDatabase.getInstance().dogDAO().findById(dogId)
+ }
+ }
+
+ override fun onSaveInstanceState(outState: Bundle) {
+ super.onSaveInstanceState(outState)
+ outState.putLong(EXTRA_DOG_ID, dogId)
+ }
+
+ override fun onCreateView(
+ inflater: LayoutInflater,
+ container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View? {
+ val view = inflater.inflate(R.layout.fragment_dog, container, false)
+ dogNameEditor = view.findViewById(R.id.dog_name_editor)
+ dogBreedEditor = view.findViewById(R.id.dog_breed_editor)
+ genderSpinner = view.findViewById(R.id.dog_breed_editor)
+ dogWeightEditor = view.findViewById(R.id.dog_weight_editor)
+ aggressivenessRatingBar = view.findViewById(R.id.aggressiveness_rating_bar)
+ dogOwnerText = view.findViewById(R.id.dog_owner_text)
+ dogAdmissionDateText = view.findViewById(R.id.dog_admission_date_text)
+
+ updateViewFromCurrentDog()
+
+ dogOwnerText.setOnClickListener {
+ pickOwner.launch()
+ }
+
+ dogAdmissionDateText.setOnClickListener {
+ val dateDialog = DatePickerFragment.newInstance(REQUEST_DATE, dog.admissionDate)
+ dateDialog.show(parentFragmentManager, DIALOG_DATE)
+ }
+
+ return view
+ }
+
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+ super.onViewCreated(view, savedInstanceState)
+ setupMenu()
+ }
+
+ private fun setupMenu() {
+ requireActivity().addMenuProvider(object : MenuProvider {
+ override fun onPrepareMenu(menu: Menu) {
+ super.onPrepareMenu(menu)
+ if (dogId == NEW_DOG_ID) {
+ menu.findItem(R.id.action_delete)?.isVisible = false
+ }
+ }
+
+ override fun onCreateMenu(menu: Menu, menuInflater: MenuInflater) {
+ menuInflater.inflate(R.menu.fragment_dog, menu)
+ }
+
+ override fun onMenuItemSelected(menuItem: MenuItem): Boolean {
+ return when (menuItem.itemId) {
+ R.id.action_save -> {
+ saveDog()
+ true
+ }
+ R.id.action_delete -> {
+ deleteDog()
+ true
+ }
+ else -> false
+ }
+ }
+ }, viewLifecycleOwner, Lifecycle.State.RESUMED)
+ }
+
+ private fun updateViewFromCurrentDog() {
+ dogNameEditor.setText(dog.name)
+ dogBreedEditor.setText(dog.breed)
+ genderSpinner.setSelection(dog.gender.ordinal)
+ dogWeightEditor.setText(dog.weight.toString())
+ aggressivenessRatingBar.rating = dog.aggressiveness.toFloat()
+ dogOwnerText.text = dog.owner
+ dog.admissionDate?.let {
+ dogAdmissionDateText.text = DateFormat.getDateFormat(activity).format(it)
+ }
+ }
+
+ private fun saveDog() {
+ val dogName = dogNameEditor.text.trim()
+ val dogWeight = dogWeightEditor.text.trim()
+ if (dogName.isEmpty() || dogWeight.isEmpty() || dogWeight == ".") {
+ AlertDialog.Builder(requireActivity())
+ .setTitle(R.string.create_dog_error_dialog_title)
+ .setMessage(R.string.create_dog_error_message)
+ .setNeutralButton(android.R.string.ok, null)
+ .show()
+ return
+ }
+
+ dog.name = dogName.toString()
+ dog.breed = dogBreedEditor.text.toString()
+ dog.gender = genderSpinner.selectedItemPosition.toGender()
+ dog.weight = dogWeight.toString().toFloat()
+ dog.aggressiveness = aggressivenessRatingBar.rating.toInt()
+
+ if (dog.id == NEW_DOG_ID)
+ DogDatabase.getInstance().dogDAO().insert(dog)
+ else
+ DogDatabase.getInstance().dogDAO().update(dog)
+
+ listener?.onDogSaved()
+ }
+
+ private fun deleteDog() {
+ if (dogId != NEW_DOG_ID) {
+ DogDatabase.getInstance().dogDAO().delete(dog)
+ listener?.onDogDeleted()
+ }
}
private fun onAdmissionDateChanged(requestKey: String, bundle: Bundle) {
- if(requestKey == REQUEST_DATE) {
+ if (requestKey == REQUEST_DATE) {
val year = bundle.getInt(DatePickerFragment.EXTRA_YEAR)
+ val month = bundle.getInt(DatePickerFragment.EXTRA_MONTH)
+ val day = bundle.getInt(DatePickerFragment.EXTRA_DAY)
+
+ val cal = Calendar.getInstance()
+ cal.set(year, month, day)
+ dog.admissionDate = Date().apply { time = cal.timeInMillis }
+ dogAdmissionDateText.text = dog.admissionDate?.let {
+ DateFormat.getDateFormat(activity).format(it)
+ } ?: ""
}
}
+
+ override fun onAttach(context: Context) {
+ super.onAttach(context)
+ if (context is OnInteractionListener) {
+ listener = context
+ } else {
+ throw RuntimeException("$context must implement OnInteractionListener")
+ }
+ }
+
+ override fun onDetach() {
+ super.onDetach()
+ listener = null
+ }
+
}
\ No newline at end of file
diff --git a/app/src/main/res/layout/dialog_date.xml b/app/src/main/res/layout/dialog_date.xml
new file mode 100644
index 0000000..4a43693
--- /dev/null
+++ b/app/src/main/res/layout/dialog_date.xml
@@ -0,0 +1,5 @@
+
+
+
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 69fab65..d486efd 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -1,3 +1,6 @@
MyOuafff
+ Add a dog
+ Cannot create the dog
+ Dog\'s name or weight cannot be empty
\ No newline at end of file