integrated Jetpack navigation to project so we dont have to manually code the functionallities of loading to different fragments

This commit is contained in:
Alex
2026-04-04 20:08:40 -06:00
parent eee724d4f5
commit f59624f9c3
33 changed files with 508 additions and 455 deletions

View File

@@ -3,6 +3,7 @@ import java.util.Properties
plugins {
alias(libs.plugins.android.application)
alias(libs.plugins.hilt)
alias(libs.plugins.navigation.safeargs)
}
val localProperties = Properties().apply {
@@ -64,6 +65,9 @@ dependencies {
implementation(libs.hilt.android)
annotationProcessor(libs.hilt.compiler)
implementation(libs.navigation.fragment)
implementation(libs.navigation.ui)
implementation("com.squareup.retrofit2:retrofit:2.9.0")
implementation("com.squareup.retrofit2:converter-gson:2.9.0")
implementation("com.squareup.okhttp3:logging-interceptor:4.12.0")

View File

@@ -15,12 +15,11 @@ import androidx.core.content.ContextCompat;
import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;
import androidx.fragment.app.Fragment;
import androidx.navigation.NavController;
import androidx.navigation.fragment.NavHostFragment;
import androidx.navigation.ui.NavigationUI;
import com.example.petstoremobile.R;
import com.example.petstoremobile.fragments.ChatFragment;
import com.example.petstoremobile.fragments.ListFragment;
import com.example.petstoremobile.fragments.ProfileFragment;
import com.example.petstoremobile.services.ChatNotificationService;
import com.google.android.material.bottomnavigation.BottomNavigationView;
@@ -29,6 +28,7 @@ import dagger.hilt.android.AndroidEntryPoint;
@AndroidEntryPoint
public class HomeActivity extends AppCompatActivity {
private BottomNavigationView bottomNav;
private NavController navController;
// Launcher to ask for notification permission
private final ActivityResultLauncher<String> requestPermissionLauncher =
@@ -52,66 +52,52 @@ public class HomeActivity extends AppCompatActivity {
//get the bottom navbar from the layout
bottomNav = findViewById(R.id.bottom_navigation);
// Initialize Navigation Component
NavHostFragment navHostFragment = (NavHostFragment) getSupportFragmentManager()
.findFragmentById(R.id.nav_host_fragment);
if (navHostFragment != null) {
navController = navHostFragment.getNavController();
NavigationUI.setupWithNavController(bottomNav, navController);
}
//load the list fragment by default if it's a fresh start
if (savedInstanceState == null) {
handleIntent(getIntent());
}
//when an item in the bottom bar is selected, load the corresponding fragment
bottomNav.setOnItemSelectedListener(item -> {
if (item.getItemId() == R.id.nav_list) {
loadFragment(new ListFragment());
return true;
} else if (item.getItemId() == R.id.nav_chat) {
loadFragment(new ChatFragment());
return true;
} else if (item.getItemId() == R.id.nav_profile) {
loadFragment(new ProfileFragment());
return true;
}
return false;
});
// Start the notification service and request for notification permission
startNotificationService();
requestNotificationPermission();
}
// Handle new intents when the activity is already running,
// like clicking a notification while the app is in use
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
handleIntent(intent);
}
// Helper function to process intents for navigation.
// like clicking a notification or just launching the app from a fresh start
private void handleIntent(Intent intent) {
if (intent != null && "chat".equals(intent.getStringExtra("navigate_to"))) {
ChatFragment chatFragment = new ChatFragment();
Bundle args = new Bundle();
if (intent.hasExtra("conversation_id")) {
Bundle args = new Bundle();
args.putLong("conversation_id", intent.getLongExtra("conversation_id", -1));
chatFragment.setArguments(args);
}
loadFragment(chatFragment);
bottomNav.setSelectedItemId(R.id.nav_chat);
} else {
loadFragment(new ListFragment());
bottomNav.setSelectedItemId(R.id.nav_list);
// Use NavController to navigate
if (navController != null) {
navController.navigate(R.id.nav_chat, args);
}
}
}
// Helper function to start the notification service in the background
// Function to start the notification service in the background
// to receive notifications when a new conversation is created
private void startNotificationService() {
Intent serviceIntent = new Intent(this, ChatNotificationService.class);
startService(serviceIntent);
}
//Helper function to request for notification permission
//Function to request for notification permission
private void requestNotificationPermission() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.POST_NOTIFICATIONS) != PackageManager.PERMISSION_GRANTED) {
@@ -119,12 +105,4 @@ public class HomeActivity extends AppCompatActivity {
}
}
}
//Helper function to load a fragment
private void loadFragment(Fragment fragment) {
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.fragment_container, fragment)
.commit();
}
}

View File

@@ -11,6 +11,8 @@ import androidx.recyclerview.widget.RecyclerView;
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
import com.bumptech.glide.load.model.GlideUrl;
import com.bumptech.glide.load.model.LazyHeaders;
import com.example.petstoremobile.R;
import com.example.petstoremobile.api.PetApi;
import com.example.petstoremobile.dtos.PetDTO;
@@ -21,6 +23,7 @@ public class PetAdapter extends RecyclerView.Adapter<PetAdapter.PetViewHolder> {
private List<PetDTO> petList;
private OnPetClickListener petClickListener;
private String baseUrl;
private String token;
// Interface for pet click on recycler view
public interface OnPetClickListener {
@@ -37,6 +40,10 @@ public class PetAdapter extends RecyclerView.Adapter<PetAdapter.PetViewHolder> {
this.baseUrl = baseUrl;
}
public void setToken(String token) {
this.token = token;
}
// Get the controls of each row in recycler view
public static class PetViewHolder extends RecyclerView.ViewHolder {
TextView tvPetName, tvPetSpeciesBreed, tvPetAge, tvPetPrice, tvPetStatus;
@@ -89,11 +96,18 @@ public class PetAdapter extends RecyclerView.Adapter<PetAdapter.PetViewHolder> {
// Load pet image using Glide with circle crop
if (baseUrl != null) {
String imageUrl = baseUrl + String.format(PetApi.PET_IMAGE_PATH, pet.getPetId());
Object loadTarget = imageUrl;
if (token != null) {
loadTarget = new GlideUrl(imageUrl, new LazyHeaders.Builder()
.addHeader("Authorization", "Bearer " + token)
.build());
}
Glide.with(holder.itemView.getContext())
.load(imageUrl)
.load(loadTarget)
.circleCrop()
.diskCacheStrategy(DiskCacheStrategy.NONE)
.skipMemoryCache(true)
.diskCacheStrategy(DiskCacheStrategy.ALL) // Changed to ALL for better performance
.placeholder(R.drawable.placeholder)
.error(R.drawable.placeholder)
.into(holder.ivPetProfile);

View File

@@ -8,6 +8,8 @@ import androidx.recyclerview.widget.RecyclerView;
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
import com.bumptech.glide.load.model.GlideUrl;
import com.bumptech.glide.load.model.LazyHeaders;
import com.example.petstoremobile.R;
import com.example.petstoremobile.api.ProductApi;
import com.example.petstoremobile.dtos.ProductDTO;
@@ -18,6 +20,7 @@ public class ProductAdapter extends RecyclerView.Adapter<ProductAdapter.ProductV
private List<ProductDTO> productList;
private OnProductClickListener listener;
private String baseUrl;
private String token;
public interface OnProductClickListener {
void onProductClick(int position);
@@ -32,6 +35,10 @@ public class ProductAdapter extends RecyclerView.Adapter<ProductAdapter.ProductV
this.baseUrl = baseUrl;
}
public void setToken(String token) {
this.token = token;
}
public static class ProductViewHolder extends RecyclerView.ViewHolder {
TextView tvName, tvCategory, tvDesc, tvPrice;
ImageView ivProductImage;
@@ -65,11 +72,18 @@ public class ProductAdapter extends RecyclerView.Adapter<ProductAdapter.ProductV
// Load product image using Glide
if (baseUrl != null) {
String imageUrl = baseUrl + String.format(ProductApi.PRODUCT_IMAGE_PATH, p.getProdId());
Object loadTarget = imageUrl;
if (token != null) {
loadTarget = new GlideUrl(imageUrl, new LazyHeaders.Builder()
.addHeader("Authorization", "Bearer " + token)
.build());
}
Glide.with(holder.itemView.getContext())
.load(imageUrl)
.load(loadTarget)
.circleCrop()
.diskCacheStrategy(DiskCacheStrategy.NONE)
.skipMemoryCache(true)
.diskCacheStrategy(DiskCacheStrategy.ALL)
.placeholder(R.drawable.placeholder)
.error(R.drawable.placeholder)
.into(holder.ivProductImage);

View File

@@ -178,6 +178,7 @@ public class ChatFragment extends Fragment implements ChatAdapter.OnChatClickLis
String role = tokenManager.getRole();
messageAdapter.setCurrentUserId(currentUserId);
messageAdapter.setToken(token);
// if token exist then connect to websocket
if (token != null) {

View File

@@ -2,9 +2,13 @@ package com.example.petstoremobile.fragments;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.view.GravityCompat;
import androidx.drawerlayout.widget.DrawerLayout;
import androidx.fragment.app.Fragment;
import androidx.navigation.NavController;
import androidx.navigation.fragment.NavHostFragment;
import android.view.LayoutInflater;
@@ -15,16 +19,6 @@ import android.widget.LinearLayout;
import com.example.petstoremobile.R;
import com.example.petstoremobile.api.auth.TokenManager;
import com.example.petstoremobile.fragments.listfragments.PetFragment;
import com.example.petstoremobile.fragments.listfragments.ServiceFragment;
import com.example.petstoremobile.fragments.listfragments.SupplierFragment;
import com.example.petstoremobile.fragments.listfragments.AdoptionFragment;
import com.example.petstoremobile.fragments.listfragments.AppointmentFragment;
import com.example.petstoremobile.fragments.listfragments.InventoryFragment;
import com.example.petstoremobile.fragments.listfragments.ProductFragment;
import com.example.petstoremobile.fragments.listfragments.ProductSupplierFragment;
import com.example.petstoremobile.fragments.listfragments.PurchaseOrderFragment;
import com.example.petstoremobile.fragments.listfragments.SaleFragment;
import javax.inject.Inject;
@@ -38,10 +32,10 @@ public class ListFragment extends Fragment {
private LinearLayout drawerPets, drawerServices, drawerSuppliers;
private View touchBlocker;
// Adoptions, Appointments, Inventory, Products
private LinearLayout drawerAdoptions, drawerAppointments, drawerInventory, drawerProducts, drawerProductSupplier, drawerPurchaseOrderView, drawerSale;
private NavController innerNavController;
@Inject TokenManager tokenManager;
@Override
@@ -62,7 +56,6 @@ public class ListFragment extends Fragment {
drawerSale=view.findViewById(R.id.drawerSale);
drawerPurchaseOrderView=view.findViewById(R.id.drawerPurchaseOrderView);
// Check user role and restrict access for STAFF
String role = tokenManager.getRole();
if ("STAFF".equalsIgnoreCase(role)) {
@@ -73,11 +66,6 @@ public class ListFragment extends Fragment {
//needed to disable touches on the innerContainer while the drawer is open
touchBlocker = view.findViewById(R.id.touchBlocker);
//Display pets fragment by default
if (savedInstanceState == null) {
loadFragment(new PetFragment());
}
//add Listeners to the drawer so user won't be able to interact with the innerContainer (the list fragments)
//while the drawer is open
drawerLayout.addDrawerListener(new DrawerLayout.DrawerListener() {
@@ -104,84 +92,39 @@ public class ListFragment extends Fragment {
});
// Click listeners for each drawer
//Pets
drawerPets.setOnClickListener(v -> {
loadFragment(new PetFragment());
drawerLayout.closeDrawers();
});
//Services
drawerServices.setOnClickListener(v -> {
loadFragment(new ServiceFragment());
drawerLayout.closeDrawers();
});
//Suppliers
drawerSuppliers.setOnClickListener(v -> {
loadFragment(new SupplierFragment());
drawerLayout.closeDrawers();
});
//Adoptions
drawerAdoptions.setOnClickListener(v -> {
loadFragment(new AdoptionFragment());
drawerLayout.closeDrawers();
});
//Appointment
drawerAppointments.setOnClickListener(v -> {
loadFragment(new AppointmentFragment());
drawerLayout.closeDrawers();
});
//Inventory
drawerInventory.setOnClickListener(v -> {
loadFragment(new InventoryFragment());
drawerLayout.closeDrawers();
});
//Products
drawerProducts.setOnClickListener(v -> {
loadFragment(new ProductFragment());
drawerLayout.closeDrawers();
});
//ProductSupplier
drawerProductSupplier.setOnClickListener(v -> {
loadFragment(new ProductSupplierFragment());
drawerLayout.closeDrawers();
});
//Purchase
drawerPurchaseOrderView.setOnClickListener(v -> {
loadFragment(new PurchaseOrderFragment());
drawerLayout.closeDrawers();
});
//Sale
drawerSale.setOnClickListener(v -> {
loadFragment(new SaleFragment());
drawerLayout.closeDrawers();
});
drawerPets.setOnClickListener(v -> navigateTo(R.id.nav_pet));
drawerServices.setOnClickListener(v -> navigateTo(R.id.nav_service));
drawerSuppliers.setOnClickListener(v -> navigateTo(R.id.nav_supplier));
drawerAdoptions.setOnClickListener(v -> navigateTo(R.id.nav_adoption));
drawerAppointments.setOnClickListener(v -> navigateTo(R.id.nav_appointment));
drawerInventory.setOnClickListener(v -> navigateTo(R.id.nav_inventory));
drawerProducts.setOnClickListener(v -> navigateTo(R.id.nav_product));
drawerProductSupplier.setOnClickListener(v -> navigateTo(R.id.nav_product_supplier));
drawerPurchaseOrderView.setOnClickListener(v -> navigateTo(R.id.nav_purchase_order));
drawerSale.setOnClickListener(v -> navigateTo(R.id.nav_sale));
return view;
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
NavHostFragment navHostFragment = (NavHostFragment) getChildFragmentManager()
.findFragmentById(R.id.inner_nav_host_fragment);
if (navHostFragment != null) {
innerNavController = navHostFragment.getNavController();
}
}
private void navigateTo(int destinationId) {
if (innerNavController != null) {
innerNavController.navigate(destinationId);
}
drawerLayout.closeDrawers();
}
//helper function to open the drawer
public void openDrawer() {
drawerLayout.openDrawer(GravityCompat.START);
}
// helper function to load the fragment into the display
public void loadFragment(Fragment fragment) {
getChildFragmentManager()
.beginTransaction()
.replace(R.id.inner_fragment_container, fragment)
.addToBackStack(null)
.commit();
}
}
}

View File

@@ -8,6 +8,7 @@ import android.view.*;
import android.widget.*;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.navigation.fragment.NavHostFragment;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
@@ -17,7 +18,6 @@ import com.example.petstoremobile.api.AdoptionApi;
import com.example.petstoremobile.dtos.AdoptionDTO;
import com.example.petstoremobile.dtos.PageResponse;
import com.example.petstoremobile.fragments.ListFragment;
import com.example.petstoremobile.fragments.listfragments.detailfragments.AdoptionDetailFragment;
import com.example.petstoremobile.utils.EventDecorator;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.prolificinteractive.materialcalendarview.CalendarDay;
@@ -68,8 +68,13 @@ public class AdoptionFragment extends Fragment implements AdoptionAdapter.OnAdop
fab.setOnClickListener(v -> openDetail(-1));
hamburger.setOnClickListener(v -> {
ListFragment lf = (ListFragment) getParentFragment();
if (lf != null) lf.openDrawer();
Fragment parent = getParentFragment();
if (parent != null) {
Fragment grandParent = parent.getParentFragment();
if (grandParent instanceof ListFragment) {
((ListFragment) grandParent).openDrawer();
}
}
});
btnToggleCalendarMode.setOnClickListener(v -> toggleCalendarMode());
@@ -197,7 +202,6 @@ public class AdoptionFragment extends Fragment implements AdoptionAdapter.OnAdop
}
private void openDetail(int position) {
AdoptionDetailFragment detail = new AdoptionDetailFragment();
Bundle args = new Bundle();
if (position != -1) {
@@ -209,11 +213,9 @@ public class AdoptionFragment extends Fragment implements AdoptionAdapter.OnAdop
args.putString("adoptionStatus", a.getAdoptionStatus());
}
detail.setArguments(args);
ListFragment lf = (ListFragment) getParentFragment();
if (lf != null) lf.loadFragment(detail);
NavHostFragment.findNavController(this).navigate(R.id.nav_adoption_detail, args);
}
@Override
public void onAdoptionClick(int position) { openDetail(position); }
}
}

View File

@@ -5,6 +5,7 @@ import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.navigation.fragment.NavHostFragment;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
@@ -28,7 +29,6 @@ import com.example.petstoremobile.dtos.ServiceDTO;
import com.example.petstoremobile.dtos.PageResponse;
import com.example.petstoremobile.dtos.PetDTO;
import com.example.petstoremobile.fragments.ListFragment;
import com.example.petstoremobile.fragments.listfragments.detailfragments.AppointmentDetailFragment;
import com.example.petstoremobile.utils.EventDecorator;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.prolificinteractive.materialcalendarview.CalendarDay;
@@ -96,9 +96,13 @@ public class AppointmentFragment extends Fragment implements AppointmentAdapter.
fabAdd.setOnClickListener(v -> openAppointmentDetails(-1));
hamburger.setOnClickListener(v -> {
ListFragment listFragment = (ListFragment) getParentFragment();
if (listFragment != null)
listFragment.openDrawer();
Fragment parent = getParentFragment();
if (parent != null) {
Fragment grandParent = parent.getParentFragment();
if (grandParent instanceof ListFragment) {
((ListFragment) grandParent).openDrawer();
}
}
});
btnToggleCalendarMode.setOnClickListener(v -> toggleCalendarMode());
@@ -205,7 +209,6 @@ public class AppointmentFragment extends Fragment implements AppointmentAdapter.
}
private void openAppointmentDetails(int position) {
AppointmentDetailFragment detailFragment = new AppointmentDetailFragment();
Bundle args = new Bundle();
if (position != -1) {
@@ -221,9 +224,7 @@ public class AppointmentFragment extends Fragment implements AppointmentAdapter.
if (a.getStoreId() != null) args.putLong("storeId", a.getStoreId());
}
detailFragment.setArguments(args);
ListFragment lf = (ListFragment) getParentFragment();
if (lf != null) lf.loadFragment(detailFragment);
NavHostFragment.findNavController(this).navigate(R.id.nav_appointment_detail, args);
}
public void onAppointmentSaved(int position, AppointmentDTO appointment) {
loadAppointmentData();
@@ -333,4 +334,4 @@ public class AppointmentFragment extends Fragment implements AppointmentAdapter.
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
recyclerView.setAdapter(adapter);
}
}
}

View File

@@ -17,7 +17,10 @@ import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.navigation.fragment.NavHostFragment;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
@@ -32,8 +35,6 @@ import com.example.petstoremobile.dtos.CategoryDTO;
import com.example.petstoremobile.dtos.InventoryDTO;
import com.example.petstoremobile.dtos.PageResponse;
import com.example.petstoremobile.fragments.ListFragment;
import com.example.petstoremobile.fragments.listfragments.detailfragments.InventoryDetailFragment;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import java.util.ArrayList;
import java.util.List;
@@ -100,9 +101,13 @@ public class InventoryFragment extends Fragment implements InventoryAdapter.OnIn
.setOnClickListener(v -> openDetail(null));
hamburger.setOnClickListener(v -> {
ListFragment lf = (ListFragment) getParentFragment();
if (lf != null)
lf.openDrawer();
Fragment parent = getParentFragment();
if (parent != null) {
Fragment grandParent = parent.getParentFragment();
if (grandParent instanceof ListFragment) {
((ListFragment) grandParent).openDrawer();
}
}
});
btnBulkDelete.setOnClickListener(v -> confirmBulkDelete());
@@ -174,7 +179,8 @@ public class InventoryFragment extends Fragment implements InventoryAdapter.OnIn
private void setupSearch(View view) {
etSearch = view.findViewById(R.id.etSearchInventory);
etSearch.addTextChangedListener(new TextWatcher() {
@Override public void beforeTextChanged(CharSequence s, int i, int i1, int i2) {
@Override
public void beforeTextChanged(CharSequence s, int i, int i1, int i2) {
}
@Override
@@ -332,7 +338,6 @@ public class InventoryFragment extends Fragment implements InventoryAdapter.OnIn
// Navigation
private void openDetail(InventoryDTO inv) {
InventoryDetailFragment detail = new InventoryDetailFragment();
Bundle args = new Bundle();
if (inv != null) {
@@ -343,12 +348,7 @@ public class InventoryFragment extends Fragment implements InventoryAdapter.OnIn
args.putInt("quantity", inv.getQuantity() != null ? inv.getQuantity() : 0);
}
detail.setArguments(args);
detail.setInventoryFragment(this);
ListFragment lf = (ListFragment) getParentFragment();
if (lf != null)
lf.loadFragment(detail);
NavHostFragment.findNavController(this).navigate(R.id.nav_inventory_detail, args);
}
public void onInventoryChanged() {

View File

@@ -2,7 +2,10 @@ package com.example.petstoremobile.fragments.listfragments;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.navigation.fragment.NavHostFragment;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
@@ -26,8 +29,6 @@ import com.example.petstoremobile.api.PetApi;
import com.example.petstoremobile.dtos.PageResponse;
import com.example.petstoremobile.dtos.PetDTO;
import com.example.petstoremobile.fragments.ListFragment;
import com.example.petstoremobile.fragments.listfragments.detailfragments.PetDetailFragment;
import com.example.petstoremobile.fragments.listfragments.listprofilefragments.PetProfileFragment;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import java.util.ArrayList;
@@ -73,10 +74,12 @@ public class PetFragment extends Fragment implements PetAdapter.OnPetClickListen
//Make the hamburger button open the drawer from listFragment
hamburger.setOnClickListener(v -> {
ListFragment listFragment = (ListFragment) getParentFragment();
//if list fragment is found then use its helper function to open the drawer
if (listFragment != null) {
listFragment.openDrawer();
Fragment parent = getParentFragment();
if (parent != null) {
Fragment grandParent = parent.getParentFragment();
if (grandParent instanceof ListFragment) {
((ListFragment) grandParent).openDrawer();
}
}
});
@@ -150,8 +153,6 @@ public class PetFragment extends Fragment implements PetAdapter.OnPetClickListen
//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();
PetDTO pet = filteredList.get(position);
@@ -168,25 +169,12 @@ public class PetFragment extends Fragment implements PetAdapter.OnPetClickListen
args.putDouble("petPrice", 0.0);
}
//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 (listFragment != null) {
listFragment.loadFragment(profileFragment);
}
NavHostFragment.findNavController(this).navigate(R.id.nav_pet_profile, args);
}
//Open the pet detail view for adding
private void openPetDetails(int position) {
PetDetailFragment detailFragment = new PetDetailFragment();
//get ListFragment to load the detail view
ListFragment listFragment = (ListFragment) getParentFragment();
if (listFragment != null) {
listFragment.loadFragment(detailFragment);
}
NavHostFragment.findNavController(this).navigate(R.id.nav_pet_detail);
}
// Called by PetAdapter when a row is clicked to open the details view
@@ -236,4 +224,4 @@ public class PetFragment extends Fragment implements PetAdapter.OnPetClickListen
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
recyclerView.setAdapter(adapter);
}
}
}

View File

@@ -6,20 +6,22 @@ import android.util.Log;
import android.view.*;
import android.widget.*;
import androidx.fragment.app.Fragment;
import androidx.navigation.fragment.NavHostFragment;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import com.example.petstoremobile.R;
import com.example.petstoremobile.adapters.ProductAdapter;
import com.example.petstoremobile.api.ProductApi;
import com.example.petstoremobile.api.auth.TokenManager;
import com.example.petstoremobile.dtos.PageResponse;
import com.example.petstoremobile.dtos.ProductDTO;
import com.example.petstoremobile.fragments.ListFragment;
import com.example.petstoremobile.fragments.listfragments.detailfragments.ProductDetailFragment;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import java.util.*;
import javax.inject.Inject;
import javax.inject.Named;
import dagger.hilt.android.AndroidEntryPoint;
import retrofit2.*;
@@ -34,6 +36,8 @@ public class ProductFragment extends Fragment implements ProductAdapter.OnProduc
private EditText etSearch;
@Inject ProductApi api;
@Inject @Named("baseUrl") String baseUrl;
@Inject TokenManager tokenManager;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
@@ -51,8 +55,13 @@ public class ProductFragment extends Fragment implements ProductAdapter.OnProduc
ImageButton hamburger = view.findViewById(R.id.btnHamburgerProduct);
hamburger.setOnClickListener(v -> {
ListFragment lf = (ListFragment) getParentFragment();
if (lf != null) lf.openDrawer();
Fragment parent = getParentFragment();
if (parent != null) {
Fragment grandParent = parent.getParentFragment();
if (grandParent instanceof ListFragment) {
((ListFragment) grandParent).openDrawer();
}
}
});
return view;
@@ -61,6 +70,8 @@ public class ProductFragment extends Fragment implements ProductAdapter.OnProduc
private void setupRecyclerView(View view) {
RecyclerView rv = view.findViewById(R.id.recyclerViewProducts);
adapter = new ProductAdapter(filteredList, this);
adapter.setBaseUrl(baseUrl);
adapter.setToken(tokenManager.getToken());
rv.setLayoutManager(new LinearLayoutManager(getContext()));
rv.setAdapter(adapter);
}
@@ -122,7 +133,6 @@ public class ProductFragment extends Fragment implements ProductAdapter.OnProduc
}
private void openDetail(int position) {
ProductDetailFragment detail = new ProductDetailFragment();
Bundle args = new Bundle();
if (position != -1) {
ProductDTO p = filteredList.get(position);
@@ -132,11 +142,9 @@ public class ProductFragment extends Fragment implements ProductAdapter.OnProduc
args.putString("prodPrice", p.getProdPrice() != null ? p.getProdPrice().toString() : "");
args.putLong("categoryId", p.getCategoryId() != null ? p.getCategoryId() : -1);
}
detail.setArguments(args);
ListFragment lf = (ListFragment) getParentFragment();
if (lf != null) lf.loadFragment(detail);
NavHostFragment.findNavController(this).navigate(R.id.nav_product_detail, args);
}
@Override
public void onProductClick(int position) { openDetail(position); }
}
}

View File

@@ -6,6 +6,7 @@ import android.util.Log;
import android.view.*;
import android.widget.*;
import androidx.fragment.app.Fragment;
import androidx.navigation.fragment.NavHostFragment;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
@@ -51,8 +52,13 @@ public class ProductSupplierFragment extends Fragment
ImageButton hamburger = view.findViewById(R.id.btnHamburgerPS);
hamburger.setOnClickListener(v -> {
ListFragment lf = (ListFragment) getParentFragment();
if (lf != null) lf.openDrawer();
Fragment parent = getParentFragment();
if (parent != null) {
Fragment grandParent = parent.getParentFragment();
if (grandParent instanceof ListFragment) {
((ListFragment) grandParent).openDrawer();
}
}
});
return view;
@@ -121,7 +127,6 @@ public class ProductSupplierFragment extends Fragment
}
private void openDetail(int position) {
ProductSupplierDetailFragment detail = new ProductSupplierDetailFragment();
Bundle args = new Bundle();
if (position != -1) {
ProductSupplierDTO ps = filteredList.get(position);
@@ -131,9 +136,7 @@ public class ProductSupplierFragment extends Fragment
args.putString("supplierName", ps.getSupplierName());
args.putString("cost", ps.getCost() != null ? ps.getCost().toString() : "");
}
detail.setArguments(args);
ListFragment lf = (ListFragment) getParentFragment();
if (lf != null) lf.loadFragment(detail);
NavHostFragment.findNavController(this).navigate(R.id.nav_product_supplier_detail, args);
}
@Override

View File

@@ -6,6 +6,7 @@ import android.util.Log;
import android.view.*;
import android.widget.*;
import androidx.fragment.app.Fragment;
import androidx.navigation.fragment.NavHostFragment;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
@@ -15,7 +16,6 @@ import com.example.petstoremobile.api.PurchaseOrderApi;
import com.example.petstoremobile.dtos.PageResponse;
import com.example.petstoremobile.dtos.PurchaseOrderDTO;
import com.example.petstoremobile.fragments.ListFragment;
import com.example.petstoremobile.fragments.listfragments.detailfragments.PurchaseOrderDetailFragment;
import java.util.*;
import javax.inject.Inject;
@@ -47,9 +47,13 @@ public class PurchaseOrderFragment extends Fragment
ImageButton hamburger = view.findViewById(R.id.btnHamburgerPO);
hamburger.setOnClickListener(v -> {
ListFragment lf = (ListFragment) getParentFragment();
if (lf != null)
lf.openDrawer();
Fragment parent = getParentFragment();
if (parent != null) {
Fragment grandParent = parent.getParentFragment();
if (grandParent instanceof ListFragment) {
((ListFragment) grandParent).openDrawer();
}
}
});
return view;
@@ -126,17 +130,13 @@ public class PurchaseOrderFragment extends Fragment
}
private void openDetail(int position) {
PurchaseOrderDetailFragment detail = new PurchaseOrderDetailFragment();
Bundle args = new Bundle();
PurchaseOrderDTO po = filteredList.get(position);
args.putLong("purchaseOrderId", po.getPurchaseOrderId());
args.putString("supplierName", po.getSupplierName());
args.putString("orderDate", po.getOrderDate());
args.putString("status", po.getStatus());
detail.setArguments(args);
ListFragment lf = (ListFragment) getParentFragment();
if (lf != null)
lf.loadFragment(detail);
NavHostFragment.findNavController(this).navigate(R.id.nav_purchase_order_detail, args);
}
@Override

View File

@@ -2,6 +2,7 @@ package com.example.petstoremobile.fragments.listfragments;
import android.os.Bundle;
import androidx.fragment.app.Fragment;
import androidx.navigation.fragment.NavHostFragment;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
@@ -17,7 +18,6 @@ import com.example.petstoremobile.R;
import com.example.petstoremobile.adapters.SaleAdapter;
import com.example.petstoremobile.api.SaleApi;
import com.example.petstoremobile.fragments.ListFragment;
import com.example.petstoremobile.fragments.listfragments.detailfragments.RefundDetailFragment;
import com.example.petstoremobile.models.Sale;
import java.util.ArrayList;
import java.util.List;
@@ -53,9 +53,12 @@ public class SaleFragment extends Fragment implements SaleAdapter.OnSaleClickLis
// Make the hamburger button open the drawer from listFragment
if (btnHamburger != null) {
btnHamburger.setOnClickListener(v -> {
ListFragment listFragment = (ListFragment) getParentFragment();
if (listFragment != null) {
listFragment.openDrawer();
Fragment parent = getParentFragment();
if (parent != null) {
Fragment grandParent = parent.getParentFragment();
if (grandParent instanceof ListFragment) {
((ListFragment) grandParent).openDrawer();
}
}
});
}
@@ -111,19 +114,14 @@ public class SaleFragment extends Fragment implements SaleAdapter.OnSaleClickLis
@Override
public void onSaleClick(int position) {
Sale sale = filteredList.get(position);
RefundDetailFragment refundFragment = new RefundDetailFragment();
Bundle args = new Bundle();
args.putInt("saleId", sale.getSaleId());
args.putString("saleDate", sale.getSaleDate());
args.putString("employeeName", sale.getEmployeeName());
args.putDouble("total", sale.getTotal());
args.putString("paymentMethod", sale.getPaymentMethod());
refundFragment.setArguments(args);
refundFragment.setSaleFragment(this);
ListFragment listFragment = (ListFragment) getParentFragment();
if (listFragment != null)
listFragment.loadFragment(refundFragment);
NavHostFragment.findNavController(this).navigate(R.id.nav_refund_detail, args);
}
public void reloadSales() {
@@ -149,4 +147,4 @@ public class SaleFragment extends Fragment implements SaleAdapter.OnSaleClickLis
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
recyclerView.setAdapter(adapter);
}
}
}

View File

@@ -2,7 +2,10 @@ package com.example.petstoremobile.fragments.listfragments;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.navigation.fragment.NavHostFragment;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
@@ -23,7 +26,6 @@ import com.example.petstoremobile.api.ServiceApi;
import com.example.petstoremobile.dtos.PageResponse;
import com.example.petstoremobile.dtos.ServiceDTO;
import com.example.petstoremobile.fragments.ListFragment;
import com.example.petstoremobile.fragments.listfragments.detailfragments.ServiceDetailFragment;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import java.util.ArrayList;
@@ -66,10 +68,12 @@ public class ServiceFragment extends Fragment implements ServiceAdapter.OnServic
//Make the hamburger button open the drawer from listFragment
hamburger.setOnClickListener(v -> {
ListFragment listFragment = (ListFragment) getParentFragment();
//if list fragment is found then use its helper function to open the drawer
if (listFragment != null) {
listFragment.openDrawer();
Fragment parent = getParentFragment();
if (parent != null) {
Fragment grandParent = parent.getParentFragment();
if (grandParent instanceof ListFragment) {
((ListFragment) grandParent).openDrawer();
}
}
});
@@ -112,8 +116,6 @@ public class ServiceFragment extends Fragment implements ServiceAdapter.OnServic
//Open the service detail view depending on the mode
private void openServiceDetails(int position) {
ServiceDetailFragment detailFragment = new ServiceDetailFragment();
//Make a bundle to pass data to the detail fragment
Bundle args = new Bundle();
args.putInt("position", position);
@@ -128,16 +130,7 @@ public class ServiceFragment extends Fragment implements ServiceAdapter.OnServic
args.putDouble("servicePrice", service.getServicePrice());
}
//send the bundle to the detail fragment to display
detailFragment.setArguments(args);
//set the service fragment to the parent so we refer back to service view when save or delete is done
detailFragment.setServiceFragment(this);
//get ListFragment to load the the detail view
ListFragment listFragment = (ListFragment) getParentFragment();
if (listFragment != null) {
listFragment.loadFragment(detailFragment);
}
NavHostFragment.findNavController(this).navigate(R.id.nav_service_detail, args);
}
// Called by ServiceAdapter when a row is clicked to open the details view
@@ -188,4 +181,4 @@ public class ServiceFragment extends Fragment implements ServiceAdapter.OnServic
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
recyclerView.setAdapter(adapter);
}
}
}

View File

@@ -2,7 +2,10 @@ package com.example.petstoremobile.fragments.listfragments;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.navigation.fragment.NavHostFragment;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
@@ -23,7 +26,6 @@ import com.example.petstoremobile.api.SupplierApi;
import com.example.petstoremobile.dtos.PageResponse;
import com.example.petstoremobile.dtos.SupplierDTO;
import com.example.petstoremobile.fragments.ListFragment;
import com.example.petstoremobile.fragments.listfragments.detailfragments.SupplierDetailFragment;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import java.util.ArrayList;
@@ -66,10 +68,12 @@ public class SupplierFragment extends Fragment implements SupplierAdapter.OnSupp
//Make the hamburger button open the drawer from listFragment
hamburger.setOnClickListener(v -> {
ListFragment listFragment = (ListFragment) getParentFragment();
//if list fragment is found then use its helper function to open the drawer
if (listFragment != null) {
listFragment.openDrawer();
Fragment parent = getParentFragment();
if (parent != null) {
Fragment grandParent = parent.getParentFragment();
if (grandParent instanceof ListFragment) {
((ListFragment) grandParent).openDrawer();
}
}
});
@@ -113,8 +117,6 @@ public class SupplierFragment extends Fragment implements SupplierAdapter.OnSupp
//Open the supplier detail view depending on the mode
private void openSupplierDetails(int position) {
SupplierDetailFragment detailFragment = new SupplierDetailFragment();
//Make a bundle to pass data to the detail fragment
Bundle args = new Bundle();
args.putInt("position", position);
@@ -130,16 +132,7 @@ public class SupplierFragment extends Fragment implements SupplierAdapter.OnSupp
args.putString("supPhone", supplier.getSupPhone());
}
//send the bundle to the detail fragment to display
detailFragment.setArguments(args);
//set the supplier fragment to the parent so we refer back to supplier view when save or delete is done
detailFragment.setSupplierFragment(this);
//get ListFragment to load the the detail view
ListFragment listFragment = (ListFragment) getParentFragment();
if (listFragment != null) {
listFragment.loadFragment(detailFragment);
}
NavHostFragment.findNavController(this).navigate(R.id.nav_supplier_detail, args);
}

View File

@@ -8,6 +8,8 @@ import android.widget.*;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.Fragment;
import androidx.navigation.fragment.NavHostFragment;
import com.example.petstoremobile.R;
import com.example.petstoremobile.adapters.BlackTextArrayAdapter;
import com.example.petstoremobile.api.*;
@@ -259,7 +261,6 @@ public class AdoptionDetailFragment extends Fragment {
}
private void navigateBack() {
ListFragment lf = (ListFragment) getParentFragment();
if (lf != null) lf.getChildFragmentManager().popBackStack();
NavHostFragment.findNavController(this).popBackStack();
}
}
}

View File

@@ -8,6 +8,8 @@ import android.widget.*;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.Fragment;
import androidx.navigation.fragment.NavHostFragment;
import com.example.petstoremobile.R;
import com.example.petstoremobile.adapters.BlackTextArrayAdapter;
import com.example.petstoremobile.api.*;
@@ -447,7 +449,6 @@ public class AppointmentDetailFragment extends Fragment {
}
private void navigateBack() {
ListFragment lf = (ListFragment) getParentFragment();
if (lf != null) lf.getChildFragmentManager().popBackStack();
NavHostFragment.findNavController(this).popBackStack();
}
}
}

View File

@@ -16,6 +16,7 @@ import android.widget.Toast;
import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.Fragment;
import androidx.navigation.fragment.NavHostFragment;
import com.example.petstoremobile.R;
import com.example.petstoremobile.adapters.BlackTextArrayAdapter;
@@ -327,9 +328,7 @@ public class InventoryDetailFragment extends Fragment {
}
private void navigateBack() {
ListFragment lf = (ListFragment) getParentFragment();
if (lf != null)
lf.getChildFragmentManager().popBackStack();
NavHostFragment.findNavController(this).popBackStack();
}
private void setButtonsEnabled(boolean enabled) {
@@ -337,4 +336,4 @@ public class InventoryDetailFragment extends Fragment {
btnDelete.setEnabled(enabled);
btnBack.setEnabled(enabled);
}
}
}

View File

@@ -7,6 +7,7 @@ import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import androidx.core.content.ContextCompat;
import androidx.fragment.app.Fragment;
import androidx.navigation.fragment.NavHostFragment;
import android.util.Log;
import android.view.LayoutInflater;
@@ -44,15 +45,9 @@ public class PetDetailFragment extends Fragment {
private Button btnSavePet, btnDeletePet, btnBack;
private int petId;
private boolean isEditing = false;
private PetFragment petFragment;
@Inject PetApi petApi;
//set the pet fragment to the parent so we refer back to pet view when save or delete is done
public void setPetFragment(PetFragment fragment) {
this.petFragment = fragment;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
@@ -178,14 +173,7 @@ public class PetDetailFragment extends Fragment {
//Helper method to navigate back to the list
private void navigateBack() {
ListFragment listFragment = (ListFragment) getParentFragment();
if (listFragment != null) {
// If editing pop back twice to get back to PetDetail Fragment instead of PetProfileFragment
if (isEditing) {
listFragment.getChildFragmentManager().popBackStack();
}
listFragment.getChildFragmentManager().popBackStack();
}
NavHostFragment.findNavController(this).popBackStack();
}
//helper function to check if pet is being edited or added and show the view accordingly
@@ -244,4 +232,4 @@ public class PetDetailFragment extends Fragment {
spinnerPetStatus.setAdapter(adapter);
}
}
}

View File

@@ -17,13 +17,17 @@ import androidx.appcompat.app.AlertDialog;
import androidx.core.content.ContextCompat;
import androidx.core.content.FileProvider;
import androidx.fragment.app.Fragment;
import androidx.navigation.fragment.NavHostFragment;
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
import com.bumptech.glide.load.model.GlideUrl;
import com.bumptech.glide.load.model.LazyHeaders;
import com.example.petstoremobile.R;
import com.example.petstoremobile.adapters.BlackTextArrayAdapter;
import com.example.petstoremobile.api.*;
import com.example.petstoremobile.api.auth.TokenManager;
import com.example.petstoremobile.dtos.*;
import com.example.petstoremobile.fragments.ListFragment;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
@@ -59,6 +63,7 @@ public class ProductDetailFragment extends Fragment {
@Inject ProductApi productApi;
@Inject CategoryApi categoryApi;
@Inject @Named("baseUrl") String baseUrl;
@Inject TokenManager tokenManager;
private ActivityResultLauncher<Intent> galleryLauncher;
private ActivityResultLauncher<Uri> cameraLauncher;
@@ -254,10 +259,18 @@ public class ProductDetailFragment extends Fragment {
//load the product image from the backend
private void loadProductImage() {
String imageUrl = baseUrl + String.format(Locale.US, ProductApi.PRODUCT_IMAGE_PATH, prodId);
String token = tokenManager.getToken();
Object loadTarget = imageUrl;
if (token != null) {
loadTarget = new GlideUrl(imageUrl, new LazyHeaders.Builder()
.addHeader("Authorization", "Bearer " + token)
.build());
}
Glide.with(this)
.load(imageUrl)
.diskCacheStrategy(DiskCacheStrategy.NONE)
.skipMemoryCache(true)
.load(loadTarget)
.diskCacheStrategy(DiskCacheStrategy.ALL)
.placeholder(R.drawable.placeholder2)
.error(R.drawable.placeholder2)
.into(ivProductImage);
@@ -398,7 +411,6 @@ public class ProductDetailFragment extends Fragment {
}
private void navigateBack() {
ListFragment lf = (ListFragment) getParentFragment();
if (lf != null) lf.getChildFragmentManager().popBackStack();
NavHostFragment.findNavController(this).popBackStack();
}
}

View File

@@ -7,6 +7,8 @@ import android.widget.*;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.Fragment;
import androidx.navigation.fragment.NavHostFragment;
import com.example.petstoremobile.R;
import com.example.petstoremobile.adapters.BlackTextArrayAdapter;
import com.example.petstoremobile.api.*;
@@ -222,7 +224,6 @@ public class ProductSupplierDetailFragment extends Fragment {
}
private void navigateBack() {
ListFragment lf = (ListFragment) getParentFragment();
if (lf != null) lf.getChildFragmentManager().popBackStack();
NavHostFragment.findNavController(this).popBackStack();
}
}
}

View File

@@ -6,6 +6,8 @@ import android.view.*;
import android.widget.*;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.navigation.fragment.NavHostFragment;
import com.example.petstoremobile.R;
import com.example.petstoremobile.fragments.ListFragment;
@@ -49,8 +51,7 @@ public class PurchaseOrderDetailFragment extends Fragment {
}
btnBack.setOnClickListener(v -> {
ListFragment lf = (ListFragment) getParentFragment();
if (lf != null) lf.getChildFragmentManager().popBackStack();
NavHostFragment.findNavController(this).popBackStack();
});
return view;

View File

@@ -2,6 +2,8 @@ package com.example.petstoremobile.fragments.listfragments.detailfragments;
import android.os.Bundle;
import androidx.fragment.app.Fragment;
import androidx.navigation.fragment.NavHostFragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -14,7 +16,6 @@ import android.widget.Toast;
import com.example.petstoremobile.R;
import com.example.petstoremobile.adapters.BlackTextArrayAdapter;
import com.example.petstoremobile.api.SaleApi;
import com.example.petstoremobile.fragments.ListFragment;
import com.example.petstoremobile.fragments.listfragments.SaleFragment;
import com.example.petstoremobile.utils.ActivityLogger;
import com.example.petstoremobile.utils.InputValidator;
@@ -119,9 +120,7 @@ public class RefundDetailFragment extends Fragment {
}
private void goBack() {
ListFragment listFragment = (ListFragment) getParentFragment();
if (listFragment != null)
listFragment.getChildFragmentManager().popBackStack();
NavHostFragment.findNavController(this).popBackStack();
}
private void initViews(View view) {
@@ -141,4 +140,4 @@ public class RefundDetailFragment extends Fragment {
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinnerRefundPayment.setAdapter(adapter);
}
}
}

View File

@@ -4,6 +4,7 @@ import android.os.Bundle;
import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.Fragment;
import androidx.navigation.fragment.NavHostFragment;
import android.util.Log;
import android.view.LayoutInflater;
@@ -17,7 +18,6 @@ import android.widget.Toast;
import com.example.petstoremobile.R;
import com.example.petstoremobile.api.ServiceApi;
import com.example.petstoremobile.dtos.ServiceDTO;
import com.example.petstoremobile.fragments.ListFragment;
import com.example.petstoremobile.fragments.listfragments.ServiceFragment;
import com.example.petstoremobile.utils.ActivityLogger;
import com.example.petstoremobile.utils.InputValidator;
@@ -164,10 +164,7 @@ public class ServiceDetailFragment extends Fragment {
//Helper method to navigate back to the list
private void navigateBack() {
ListFragment listFragment = (ListFragment) getParentFragment();
if (listFragment != null) {
listFragment.getChildFragmentManager().popBackStack();
}
NavHostFragment.findNavController(this).popBackStack();
}
//helper function to check if service is being edited or added and show the view accordingly

View File

@@ -4,6 +4,7 @@ import android.os.Bundle;
import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.Fragment;
import androidx.navigation.fragment.NavHostFragment;
import android.util.Log;
import android.view.LayoutInflater;
@@ -17,8 +18,6 @@ import android.widget.Toast;
import com.example.petstoremobile.R;
import com.example.petstoremobile.api.SupplierApi;
import com.example.petstoremobile.dtos.SupplierDTO;
import com.example.petstoremobile.fragments.ListFragment;
import com.example.petstoremobile.fragments.listfragments.SupplierFragment;
import com.example.petstoremobile.utils.ActivityLogger;
import com.example.petstoremobile.utils.InputValidator;
@@ -37,15 +36,9 @@ public class SupplierDetailFragment extends Fragment {
private Button btnSaveSupplier, btnDeleteSupplier, btnBack;
private int supId;
private boolean isEditing = false;
private SupplierFragment supplierFragment;
@Inject SupplierApi supplierApi;
//set the supplier fragment to the parent so we refer back to supplier view when save or delete is done
public void setSupplierFragment(SupplierFragment fragment) {
this.supplierFragment = fragment;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
@@ -167,10 +160,7 @@ public class SupplierDetailFragment extends Fragment {
//Helper method to navigate back to the list
private void navigateBack() {
ListFragment listFragment = (ListFragment) getParentFragment();
if (listFragment != null) {
listFragment.getChildFragmentManager().popBackStack();
}
NavHostFragment.findNavController(this).popBackStack();
}
//helper function to check if supplier is being edited or added and show the view accordingly
@@ -217,4 +207,4 @@ public class SupplierDetailFragment extends Fragment {
btnDeleteSupplier = view.findViewById(R.id.btnDeleteSupplier);
btnBack = view.findViewById(R.id.btnBack);
}
}
}

View File

@@ -14,6 +14,7 @@ import androidx.appcompat.app.AlertDialog;
import androidx.core.content.ContextCompat;
import androidx.core.content.FileProvider;
import androidx.fragment.app.Fragment;
import androidx.navigation.fragment.NavHostFragment;
import android.provider.MediaStore;
import android.util.Log;
@@ -27,8 +28,11 @@ import android.widget.Toast;
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
import com.bumptech.glide.load.model.GlideUrl;
import com.bumptech.glide.load.model.LazyHeaders;
import com.example.petstoremobile.R;
import com.example.petstoremobile.api.PetApi;
import com.example.petstoremobile.api.auth.TokenManager;
import com.example.petstoremobile.fragments.ListFragment;
import com.example.petstoremobile.fragments.listfragments.detailfragments.PetDetailFragment;
@@ -62,6 +66,7 @@ public class PetProfileFragment extends Fragment {
@Inject PetApi petApi;
@Inject @Named("baseUrl") String baseUrl;
@Inject TokenManager tokenManager;
// launchers for camera and gallery
private ActivityResultLauncher<Intent> galleryLauncher;
@@ -148,26 +153,13 @@ public class PetProfileFragment extends Fragment {
//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();
}
NavHostFragment.findNavController(this).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);
}
NavHostFragment.findNavController(this).navigate(R.id.nav_pet_detail, getArguments());
});
//Make change photo button ask user to select a new photo
@@ -209,11 +201,18 @@ public class PetProfileFragment extends Fragment {
// Helper function to load pet image from backend
private void loadPetImage(int petId) {
String imageUrl = baseUrl + String.format(Locale.US, PetApi.PET_IMAGE_PATH, petId);
String token = tokenManager.getToken();
Object loadTarget = imageUrl;
if (token != null) {
loadTarget = new GlideUrl(imageUrl, new LazyHeaders.Builder()
.addHeader("Authorization", "Bearer " + token)
.build());
}
Glide.with(this)
.load(imageUrl)
.diskCacheStrategy(DiskCacheStrategy.NONE)
.skipMemoryCache(true)
.load(loadTarget)
.diskCacheStrategy(DiskCacheStrategy.ALL)
.placeholder(R.drawable.placeholder)
.error(R.drawable.placeholder)
.listener(new com.bumptech.glide.request.RequestListener<android.graphics.drawable.Drawable>() {

View File

@@ -7,12 +7,14 @@
android:orientation="vertical"
android:background="@color/primary_dark">
<FrameLayout
android:id="@+id/fragment_container"
<androidx.fragment.app.FragmentContainerView
android:id="@+id/nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:background="@color/background_grey"/>
app:defaultNavHost="true"
app:navGraph="@navigation/nav_graph" />
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/bottom_navigation"

View File

@@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.drawerlayout.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/drawerLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
@@ -10,10 +11,13 @@
android:layout_height="match_parent"
android:background="@color/background_grey">
<FrameLayout
android:id="@+id/inner_fragment_container"
<androidx.fragment.app.FragmentContainerView
android:id="@+id/inner_nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
android:layout_height="match_parent"
app:defaultNavHost="false"
app:navGraph="@navigation/list_nav_graph" />
<View
android:id="@+id/touchBlocker"
@@ -33,8 +37,6 @@
android:orientation="vertical"
android:background="@color/primary_dark">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
@@ -87,14 +89,12 @@
android:paddingStart="16dp"
android:paddingEnd="16dp"
android:background="?attr/selectableItemBackground">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Pets"
android:textColor="@color/white"
android:textSize="15sp"/>
</LinearLayout>
<LinearLayout
@@ -106,14 +106,12 @@
android:paddingStart="16dp"
android:paddingEnd="16dp"
android:background="?attr/selectableItemBackground">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Services"
android:textColor="@color/white"
android:textSize="15sp"/>
</LinearLayout>
<LinearLayout
@@ -125,39 +123,30 @@
android:paddingStart="16dp"
android:paddingEnd="16dp"
android:background="?attr/selectableItemBackground">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Suppliers"
android:textColor="@color/white"
android:textSize="15sp"/>
</LinearLayout>
<!-- Appointments -->
<LinearLayout
android:id="@+id/drawerAppointments"
android:layout_width="match_parent"
android:layout_height="48dp"
android:orientation="horizontal"
android:gravity="center_vertical"
android:paddingStart="16dp"
android:paddingEnd="16dp"
android:background="?attr/selectableItemBackground">
<TextView
<LinearLayout
android:id="@+id/drawerAppointments"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Appointments"
android:textColor="@color/white"
android:textSize="15sp"/>
</LinearLayout>
<!-- Adoptions -->
android:layout_height="48dp"
android:orientation="horizontal"
android:gravity="center_vertical"
android:paddingStart="16dp"
android:paddingEnd="16dp"
android:background="?attr/selectableItemBackground">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Appointments"
android:textColor="@color/white"
android:textSize="15sp"/>
</LinearLayout>
<LinearLayout
android:id="@+id/drawerAdoptions"
@@ -168,19 +157,14 @@
android:paddingStart="16dp"
android:paddingEnd="16dp"
android:background="?attr/selectableItemBackground">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Adoptions"
android:textColor="@color/white"
android:textSize="15sp"/>
</LinearLayout>
<!-- Inventory -->
<LinearLayout
android:id="@+id/drawerInventory"
android:layout_width="match_parent"
@@ -190,19 +174,14 @@
android:paddingStart="16dp"
android:paddingEnd="16dp"
android:background="?attr/selectableItemBackground">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Inventory"
android:textColor="@color/white"
android:textSize="15sp"/>
</LinearLayout>
<!-- Product -->
<LinearLayout
android:id="@+id/drawerProducts"
android:layout_width="match_parent"
@@ -212,88 +191,65 @@
android:paddingStart="16dp"
android:paddingEnd="16dp"
android:background="?attr/selectableItemBackground">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Products"
android:textColor="@color/white"
android:textSize="15sp"/>
</LinearLayout>
<!-- Sale -->
<LinearLayout
android:id="@+id/drawerSale"
android:layout_width="match_parent"
android:layout_height="48dp"
android:orientation="horizontal"
android:gravity="center_vertical"
android:paddingStart="16dp"
android:paddingEnd="16dp"
android:background="?attr/selectableItemBackground">
<TextView
<LinearLayout
android:id="@+id/drawerSale"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Sale"
android:textColor="@color/white"
android:textSize="15sp"/>
</LinearLayout>
<!-- PurchaseOrder -->
<LinearLayout
android:id="@+id/drawerPurchaseOrderView"
android:layout_width="match_parent"
android:layout_height="48dp"
android:orientation="horizontal"
android:gravity="center_vertical"
android:paddingStart="16dp"
android:paddingEnd="16dp"
android:background="?attr/selectableItemBackground">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="PurchaseOrder"
android:textColor="@color/white"
android:textSize="15sp"/>
</LinearLayout>
<!-- ProductSupplier -->
<LinearLayout
android:id="@+id/drawerProductSupplier"
android:layout_height="48dp"
android:orientation="horizontal"
android:gravity="center_vertical"
android:paddingStart="16dp"
android:paddingEnd="16dp"
android:background="?attr/selectableItemBackground">
<TextView
android:layout_width="match_parent"
android:layout_height="48dp"
android:orientation="horizontal"
android:gravity="center_vertical"
android:paddingStart="16dp"
android:paddingEnd="16dp"
android:background="?attr/selectableItemBackground">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="ProductSupplier"
android:textColor="@color/white"
android:textSize="15sp"/>
android:layout_height="wrap_content"
android:text="Sale"
android:textColor="@color/white"
android:textSize="15sp"/>
</LinearLayout>
<LinearLayout
android:id="@+id/drawerPurchaseOrderView"
android:layout_width="match_parent"
android:layout_height="48dp"
android:orientation="horizontal"
android:gravity="center_vertical"
android:paddingStart="16dp"
android:paddingEnd="16dp"
android:background="?attr/selectableItemBackground">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="PurchaseOrder"
android:textColor="@color/white"
android:textSize="15sp"/>
</LinearLayout>
<LinearLayout
android:id="@+id/drawerProductSupplier"
android:layout_width="match_parent"
android:layout_height="48dp"
android:orientation="horizontal"
android:gravity="center_vertical"
android:paddingStart="16dp"
android:paddingEnd="16dp"
android:background="?attr/selectableItemBackground">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="ProductSupplier"
android:textColor="@color/white"
android:textSize="15sp"/>
</LinearLayout>
</LinearLayout>
</LinearLayout>
</androidx.drawerlayout.widget.DrawerLayout>

View File

@@ -0,0 +1,136 @@
<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/list_nav_graph"
app:startDestination="@id/nav_pet">
<!-- List Screens -->
<fragment
android:id="@+id/nav_pet"
android:name="com.example.petstoremobile.fragments.listfragments.PetFragment"
android:label="Pets"
tools:layout="@layout/fragment_pet" />
<fragment
android:id="@+id/nav_service"
android:name="com.example.petstoremobile.fragments.listfragments.ServiceFragment"
android:label="Services"
tools:layout="@layout/fragment_service" />
<fragment
android:id="@+id/nav_supplier"
android:name="com.example.petstoremobile.fragments.listfragments.SupplierFragment"
android:label="Suppliers"
tools:layout="@layout/fragment_supplier" />
<fragment
android:id="@+id/nav_adoption"
android:name="com.example.petstoremobile.fragments.listfragments.AdoptionFragment"
android:label="Adoptions"
tools:layout="@layout/fragment_adoption" />
<fragment
android:id="@+id/nav_appointment"
android:name="com.example.petstoremobile.fragments.listfragments.AppointmentFragment"
android:label="Appointments"
tools:layout="@layout/fragment_appointment" />
<fragment
android:id="@+id/nav_inventory"
android:name="com.example.petstoremobile.fragments.listfragments.InventoryFragment"
android:label="Inventory"
tools:layout="@layout/fragment_inventory" />
<fragment
android:id="@+id/nav_product"
android:name="com.example.petstoremobile.fragments.listfragments.ProductFragment"
android:label="Products"
tools:layout="@layout/fragment_product" />
<fragment
android:id="@+id/nav_product_supplier"
android:name="com.example.petstoremobile.fragments.listfragments.ProductSupplierFragment"
android:label="Product Suppliers"
tools:layout="@layout/fragment_product_supplier" />
<fragment
android:id="@+id/nav_purchase_order"
android:name="com.example.petstoremobile.fragments.listfragments.PurchaseOrderFragment"
android:label="Purchase Orders"
tools:layout="@layout/fragment_purchase_order" />
<fragment
android:id="@+id/nav_sale"
android:name="com.example.petstoremobile.fragments.listfragments.SaleFragment"
android:label="Sales"
tools:layout="@layout/fragment_sale" />
<!-- Detail Screens -->
<fragment
android:id="@+id/nav_pet_detail"
android:name="com.example.petstoremobile.fragments.listfragments.detailfragments.PetDetailFragment"
android:label="Pet Details"
tools:layout="@layout/fragment_pet_detail" />
<fragment
android:id="@+id/nav_pet_profile"
android:name="com.example.petstoremobile.fragments.listfragments.listprofilefragments.PetProfileFragment"
android:label="Pet Profile"
tools:layout="@layout/fragment_pet_profile" />
<fragment
android:id="@+id/nav_adoption_detail"
android:name="com.example.petstoremobile.fragments.listfragments.detailfragments.AdoptionDetailFragment"
android:label="Adoption Details"
tools:layout="@layout/fragment_adoption_detail" />
<fragment
android:id="@+id/nav_service_detail"
android:name="com.example.petstoremobile.fragments.listfragments.detailfragments.ServiceDetailFragment"
android:label="Service Details"
tools:layout="@layout/fragment_service_detail" />
<fragment
android:id="@+id/nav_supplier_detail"
android:name="com.example.petstoremobile.fragments.listfragments.detailfragments.SupplierDetailFragment"
android:label="Supplier Details"
tools:layout="@layout/fragment_supplier_detail" />
<fragment
android:id="@+id/nav_inventory_detail"
android:name="com.example.petstoremobile.fragments.listfragments.detailfragments.InventoryDetailFragment"
android:label="Inventory Details"
tools:layout="@layout/fragment_inventory_detail" />
<fragment
android:id="@+id/nav_appointment_detail"
android:name="com.example.petstoremobile.fragments.listfragments.detailfragments.AppointmentDetailFragment"
android:label="Appointment Details"
tools:layout="@layout/fragment_appointment_detail" />
<fragment
android:id="@+id/nav_purchase_order_detail"
android:name="com.example.petstoremobile.fragments.listfragments.detailfragments.PurchaseOrderDetailFragment"
android:label="Purchase Order Details"
tools:layout="@layout/fragment_purchase_order_detail" />
<fragment
android:id="@+id/nav_product_supplier_detail"
android:name="com.example.petstoremobile.fragments.listfragments.detailfragments.ProductSupplierDetailFragment"
android:label="Product Supplier Details"
tools:layout="@layout/fragment_product_supplier_detail" />
<fragment
android:id="@+id/nav_product_detail"
android:name="com.example.petstoremobile.fragments.listfragments.detailfragments.ProductDetailFragment"
android:label="Product Details"
tools:layout="@layout/fragment_product_detail" />
<fragment
android:id="@+id/nav_refund_detail"
android:name="com.example.petstoremobile.fragments.listfragments.detailfragments.RefundDetailFragment"
android:label="Refund Details"
tools:layout="@layout/fragment_refund_detail" />
</navigation>

View File

@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/nav_graph"
app:startDestination="@id/nav_list">
<fragment
android:id="@+id/nav_list"
android:name="com.example.petstoremobile.fragments.ListFragment"
android:label="List"
tools:layout="@layout/fragment_list" />
<fragment
android:id="@+id/nav_chat"
android:name="com.example.petstoremobile.fragments.ChatFragment"
android:label="Chat"
tools:layout="@layout/fragment_chat" />
<fragment
android:id="@+id/nav_profile"
android:name="com.example.petstoremobile.fragments.ProfileFragment"
android:label="Profile"
tools:layout="@layout/fragment_profile" />
</navigation>