diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 1e0ba27f..016d3601 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -23,7 +23,7 @@
android:theme="@style/Theme.PetStoreMobile">
{
if (item.getItemId() == R.id.nav_list) {
diff --git a/app/src/main/java/com/example/petstoremobile/activities/MainActivity.java b/app/src/main/java/com/example/petstoremobile/activities/MainActivity.java
index c57caec1..974983da 100644
--- a/app/src/main/java/com/example/petstoremobile/activities/MainActivity.java
+++ b/app/src/main/java/com/example/petstoremobile/activities/MainActivity.java
@@ -9,7 +9,6 @@ import android.widget.Toast;
import androidx.activity.EdgeToEdge;
import androidx.appcompat.app.AppCompatActivity;
-import androidx.core.content.ContextCompat;
import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;
diff --git a/app/src/main/java/com/example/petstoremobile/fragments/listfragments/PetFragment.java b/app/src/main/java/com/example/petstoremobile/fragments/listfragments/PetFragment.java
index d436538e..6fc7f472 100644
--- a/app/src/main/java/com/example/petstoremobile/fragments/listfragments/PetFragment.java
+++ b/app/src/main/java/com/example/petstoremobile/fragments/listfragments/PetFragment.java
@@ -15,6 +15,7 @@ import com.example.petstoremobile.R;
import com.example.petstoremobile.adapters.PetAdapter;
import com.example.petstoremobile.fragments.ListFragment;
import com.example.petstoremobile.fragments.listfragments.detailfragments.PetDetailFragment;
+import com.example.petstoremobile.fragments.listfragments.listprofilefragments.PetProfileFragment;
import com.example.petstoremobile.models.Pet;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
@@ -54,31 +55,35 @@ public class PetFragment extends Fragment implements PetAdapter.OnPetClickListen
return view;
}
- //Open the pet detail view depending on the mode
+ //Open pet profile
+ private void openPetProfile(int position) {
+ PetProfileFragment profileFragment = new PetProfileFragment();
+
+ //Make a bundle to pass data to the profile fragment
+ Bundle args = new Bundle();
+ Pet pet = petList.get(position);
+ args.putInt("petId", pet.getPetId());
+ args.putString("petName", pet.getPetName());
+ args.putString("petSpecies", pet.getPetSpecies());
+ args.putString("petBreed", pet.getPetBreed());
+ args.putInt("petAge", pet.getPetAge());
+ args.putString("petStatus", pet.getPetStatus());
+ args.putDouble("petPrice", pet.getPetPrice());
+
+ //send the bundle to the profile fragment to display
+ profileFragment.setArguments(args);
+
+ //get ListFragment to load the the pet profile view
+ ListFragment listFragment = (ListFragment) getParentFragment();
+ if (profileFragment != null) {
+ listFragment.loadFragment(profileFragment);
+ }
+ }
+
+ //Open the pet detail view for adding
private void openPetDetails(int position) {
PetDetailFragment detailFragment = new PetDetailFragment();
- //Make a bundle to pass data to the detail fragment
- Bundle args = new Bundle();
- args.putInt("position", position);
-
- //if editing a pet, add the pet data to the bundle
- if (position != -1) {
- Pet pet = petList.get(position);
- args.putInt("petId", pet.getPetId());
- args.putString("petName", pet.getPetName());
- args.putString("petSpecies", pet.getPetSpecies());
- args.putString("petBreed", pet.getPetBreed());
- args.putInt("petAge", pet.getPetAge());
- args.putString("petStatus", pet.getPetStatus());
- args.putDouble("petPrice", pet.getPetPrice());
- }
-
- //send the bundle to the detail fragment to display
- detailFragment.setArguments(args);
- //set the pet fragment to the parent so we refer back to pet view when save or delete is done
- detailFragment.setPetFragment(this);
-
//get ListFragment to load the the detail view
ListFragment listFragment = (ListFragment) getParentFragment();
if (listFragment != null) {
@@ -87,25 +92,26 @@ public class PetFragment extends Fragment implements PetAdapter.OnPetClickListen
}
// Called by PetDetailFragment when save or delete is done
- public void onPetSaved(int position, Pet pet) {
- if (position == -1) {
- petList.add(pet);
- adapter.notifyItemInserted(petList.size() - 1);
- } else {
- petList.set(position, pet);
- adapter.notifyItemChanged(position);
- }
- }
-
- public void onPetDeleted(int position) {
- petList.remove(position);
- adapter.notifyItemRemoved(position);
- }
+ //TODO: REPLACE THIS WITH JUST RELOADING THE LIST BY FETCHING FROM THE BACKEND
+// public void onPetSaved(int position, Pet pet) {
+// if (position == -1) {
+// petList.add(pet);
+// adapter.notifyItemInserted(petList.size() - 1);
+// } else {
+// petList.set(position, pet);
+// adapter.notifyItemChanged(position);
+// }
+// }
+//
+// public void onPetDeleted(int position) {
+// petList.remove(position);
+// adapter.notifyItemRemoved(position);
+// }
// Called by PetAdapter when a row is clicked to open the details view
@Override
public void onPetClick(int position) {
- openPetDetails(position);
+ openPetProfile(position);
}
// Helper function to get a list of all pets (Loads hardcoded sample data for now) TODO: REPLACE THIS WITH A METHOD THAT GETS DATA FROM THE DATABASE
diff --git a/app/src/main/java/com/example/petstoremobile/fragments/listfragments/listprofilefragments/PetProfileFragment.java b/app/src/main/java/com/example/petstoremobile/fragments/listfragments/listprofilefragments/PetProfileFragment.java
new file mode 100644
index 00000000..280789e8
--- /dev/null
+++ b/app/src/main/java/com/example/petstoremobile/fragments/listfragments/listprofilefragments/PetProfileFragment.java
@@ -0,0 +1,177 @@
+package com.example.petstoremobile.fragments.listfragments.listprofilefragments;
+
+import android.Manifest;
+import android.app.Activity;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.graphics.Color;
+import android.net.Uri;
+import android.os.Bundle;
+
+import androidx.activity.result.ActivityResultLauncher;
+import androidx.activity.result.contract.ActivityResultContracts;
+import androidx.appcompat.app.AlertDialog;
+import androidx.core.content.ContextCompat;
+import androidx.core.content.FileProvider;
+import androidx.fragment.app.Fragment;
+
+import android.provider.MediaStore;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.Button;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import com.example.petstoremobile.R;
+import com.example.petstoremobile.fragments.ListFragment;
+import com.example.petstoremobile.fragments.listfragments.detailfragments.PetDetailFragment;
+
+import java.io.File;
+import java.util.Locale;
+
+public class PetProfileFragment extends Fragment {
+
+ private TextView tvPetName, tvPetSpecies, tvPetBreed, tvPetAge, tvPetPrice;
+ private Button btnBack, btnEditPet, btnChangePhoto;
+ private ImageView imgPet;
+ private Uri photoUri;
+
+ // launchers for camera and gallery
+ private ActivityResultLauncher galleryLauncher;
+ private ActivityResultLauncher cameraLauncher;
+ private ActivityResultLauncher permissionLauncher;
+
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ // Launcher to open gallery to select image
+ galleryLauncher = registerForActivityResult(
+ new ActivityResultContracts.StartActivityForResult(),
+ result -> {
+ if (result.getResultCode() == Activity.RESULT_OK && result.getData() != null) {
+ Uri selectedImage = result.getData().getData();
+ imgPet.setImageURI(selectedImage);
+ // TODO: SAVE CHANGED PHOTO TO DATABASE
+ }
+ }
+ );
+
+ // Launcher for camera to open and capture image
+ cameraLauncher = registerForActivityResult(
+ new ActivityResultContracts.TakePicture(),
+ success -> {
+ if (success) {
+ imgPet.setImageURI(null);
+ imgPet.setImageURI(photoUri);
+ // TODO: SAVE CHANGED PHOTO TO DATABASE
+ }
+ }
+ );
+
+ // Launcher to request camera permission
+ permissionLauncher = registerForActivityResult(
+ new ActivityResultContracts.RequestPermission(),
+ granted -> {
+ if (granted) {
+ launchCamera();
+ } else {
+ new AlertDialog.Builder(requireContext())
+ .setTitle("Permission Required")
+ .setMessage("Please grant camera permission to use this feature")
+ .setPositiveButton("Open Settings", (dialog, which) -> {
+ Intent intent = new Intent(android.provider.Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
+ intent.setData(Uri.fromParts("package", requireContext().getPackageName(), null));
+ startActivity(intent);
+ })
+ .setNegativeButton("Cancel", null)
+ .show();
+ }
+ }
+ );
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ View view = inflater.inflate(R.layout.fragment_pet_profile, container, false);
+
+ // Initialize views
+ tvPetName = view.findViewById(R.id.tvPetName);
+ tvPetSpecies = view.findViewById(R.id.tvPetSpecies);
+ tvPetBreed = view.findViewById(R.id.tvPetBreed);
+ tvPetAge = view.findViewById(R.id.tvPetAge);
+ tvPetPrice = view.findViewById(R.id.tvPetPrice);
+ btnBack = view.findViewById(R.id.btnBack);
+ btnEditPet = view.findViewById(R.id.btnEditPet);
+ btnChangePhoto = view.findViewById(R.id.btnChangePhoto);
+ imgPet = view.findViewById(R.id.imgPet);
+
+
+ // Set pet details to display
+ if (getArguments() != null) {
+ tvPetName.setText(getArguments().getString("petName"));
+ tvPetSpecies.setText(getArguments().getString("petSpecies"));
+ tvPetBreed.setText(getArguments().getString("petBreed"));
+ tvPetAge.setText(String.format(Locale.getDefault(), "%d yr(s)", getArguments().getInt("petAge")));
+ tvPetPrice.setText(String.format(Locale.getDefault(), "$%.2f", getArguments().getDouble("petPrice")));
+ }
+
+ //set button click listeners
+ btnBack.setOnClickListener(v -> {
+ //get the list fragment and pop the back stack to return to the previous view (PetFragment)
+ ListFragment listFragment = (ListFragment) getParentFragment();
+ if (listFragment != null) {
+ listFragment.getChildFragmentManager().popBackStack();
+ }
+ });
+
+ //Make the edit button go to the pet detail view
+ btnEditPet.setOnClickListener(v -> {
+ if (getArguments() == null) return;
+
+ PetDetailFragment detailFragment = new PetDetailFragment();
+ //send the bundle to the pet detail fragment
+ detailFragment.setArguments(getArguments());
+
+ //get ListFragment to load the the detail view
+ ListFragment listFragment = (ListFragment) getParentFragment();
+ if (listFragment != null) {
+ listFragment.loadFragment(detailFragment);
+ }
+ });
+
+ //Make change photo button ask user to select a new photo
+ btnChangePhoto.setOnClickListener(v -> {
+ new AlertDialog.Builder(requireContext())
+ .setTitle("Change Pet Photo")
+ .setItems(new String[]{"Take Photo", "Choose from Gallery"}, (dialog, which) -> {
+ if (which == 0) {
+ // Choose Camera
+ //Checks if the user has granted the camera permission already
+ if (ContextCompat.checkSelfPermission(requireContext(), Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED) {
+ //if the permission is already granted then launch the camera
+ launchCamera();
+ } else {
+ //otherwise request the permission
+ permissionLauncher.launch(Manifest.permission.CAMERA);
+ }
+ } else {
+ Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
+ galleryLauncher.launch(intent);
+ }
+ })
+ .show();
+ });
+
+ return view;
+ }
+
+ private void launchCamera() {
+ File photoFile = new File(requireContext().getCacheDir(), "pet_photo.jpg");
+ photoUri = FileProvider.getUriForFile(requireContext(), requireContext().getPackageName() + ".fileprovider", photoFile);
+ cameraLauncher.launch(photoUri);
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_pet_profile.xml b/app/src/main/res/layout/fragment_pet_profile.xml
new file mode 100644
index 00000000..b750bd29
--- /dev/null
+++ b/app/src/main/res/layout/fragment_pet_profile.xml
@@ -0,0 +1,244 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file