Product activities , to create, view
This commit is contained in:
@@ -0,0 +1,72 @@
|
|||||||
|
package com.example.petstoremobile.adapters;
|
||||||
|
|
||||||
|
|
||||||
|
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.petstoremobile.R;
|
||||||
|
import com.example.petstoremobile.models.Product;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class ProductAdapter extends RecyclerView.Adapter<ProductAdapter.ProductViewHolder> {
|
||||||
|
|
||||||
|
private List<Product> productList;
|
||||||
|
private OnProductClickListener productClickListener;
|
||||||
|
|
||||||
|
// Interface for product click on recycler view
|
||||||
|
public interface OnProductClickListener {
|
||||||
|
void onProductClick(int position);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Constructor
|
||||||
|
public ProductAdapter(List<Product> productList, OnProductClickListener productClickListener) {
|
||||||
|
this.productList = productList;
|
||||||
|
this.productClickListener = productClickListener;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the controls of each row in recycler view
|
||||||
|
public static class ProductViewHolder extends RecyclerView.ViewHolder {
|
||||||
|
TextView tvProductName, tvProductDesc, tvCategory, tvProductPrice, tvStockQuantity;
|
||||||
|
|
||||||
|
public ProductViewHolder(@NonNull View v) {
|
||||||
|
super(v);
|
||||||
|
tvProductName = v.findViewById(R.id.tvProductName);
|
||||||
|
tvProductDesc = v.findViewById(R.id.tvProductDesc);
|
||||||
|
tvCategory = v.findViewById(R.id.tvProductCategory);
|
||||||
|
tvProductPrice = v.findViewById(R.id.tvProductPrice);
|
||||||
|
tvStockQuantity = v.findViewById(R.id.tvStockQuantity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a new row view
|
||||||
|
@NonNull
|
||||||
|
@Override
|
||||||
|
public ProductViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||||
|
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_product, parent, false);
|
||||||
|
return new ProductViewHolder(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Populate the row with product data
|
||||||
|
@Override
|
||||||
|
public void onBindViewHolder(@NonNull ProductViewHolder holder, int position) {
|
||||||
|
Product product = productList.get(position);
|
||||||
|
|
||||||
|
holder.tvProductName.setText(product.getProductName());
|
||||||
|
holder.tvProductDesc.setText(product.getProductDesc());
|
||||||
|
holder.tvCategory.setText(product.getCategory());
|
||||||
|
holder.tvProductPrice.setText("$" + String.format("%.2f", product.getProductPrice()));
|
||||||
|
holder.tvStockQuantity.setText("Stock: " + product.getStockQuantity());
|
||||||
|
|
||||||
|
// When a row is clicked, open the detail view
|
||||||
|
holder.itemView.setOnClickListener(v -> productClickListener.onProductClick(position));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getItemCount() {
|
||||||
|
return productList.size();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,148 @@
|
|||||||
|
package com.example.petstoremobile.fragments.listfragments;
|
||||||
|
|
||||||
|
// Added search/filter bar to filter products by name or category.
|
||||||
|
// Added pull-to-refresh using SwipeRefreshLayout.
|
||||||
|
|
||||||
|
import android.os.Bundle;
|
||||||
|
import androidx.fragment.app.Fragment;
|
||||||
|
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||||
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
|
||||||
|
import android.text.Editable;
|
||||||
|
import android.text.TextWatcher;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.EditText;
|
||||||
|
import com.example.petstoremobile.R;
|
||||||
|
import com.example.petstoremobile.adapters.ProductAdapter;
|
||||||
|
import com.example.petstoremobile.fragments.ListFragment;
|
||||||
|
import com.example.petstoremobile.fragments.listfragments.detailfragments.ProductDetailFragment;
|
||||||
|
import com.example.petstoremobile.models.Product;
|
||||||
|
import com.google.android.material.floatingactionbutton.FloatingActionButton;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class ProductFragment extends Fragment implements ProductAdapter.OnProductClickListener {
|
||||||
|
|
||||||
|
private List<Product> productList = new ArrayList<>();
|
||||||
|
private List<Product> filteredList = new ArrayList<>();
|
||||||
|
private ProductAdapter adapter;
|
||||||
|
private SwipeRefreshLayout swipeRefreshLayout;
|
||||||
|
private EditText etSearch;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||||
|
Bundle savedInstanceState) {
|
||||||
|
View view = inflater.inflate(R.layout.fragment_product, container, false);
|
||||||
|
|
||||||
|
loadProductData(); // TODO: Replace with actual API call when backend is ready
|
||||||
|
setupRecyclerView(view);
|
||||||
|
setupSearch(view);
|
||||||
|
setupSwipeRefresh(view);
|
||||||
|
|
||||||
|
FloatingActionButton fabAddProduct = view.findViewById(R.id.fabAddProduct);
|
||||||
|
fabAddProduct.setOnClickListener(v -> openProductDetails(-1));
|
||||||
|
|
||||||
|
return view;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Filters products by name, description, or category
|
||||||
|
private void setupSearch(View view) {
|
||||||
|
etSearch = view.findViewById(R.id.etSearchProduct);
|
||||||
|
etSearch.addTextChangedListener(new TextWatcher() {
|
||||||
|
@Override public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
|
||||||
|
@Override public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||||
|
filterProducts(s.toString());
|
||||||
|
}
|
||||||
|
@Override public void afterTextChanged(Editable s) {}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void filterProducts(String query) {
|
||||||
|
filteredList.clear();
|
||||||
|
if (query.isEmpty()) {
|
||||||
|
filteredList.addAll(productList);
|
||||||
|
} else {
|
||||||
|
String lower = query.toLowerCase();
|
||||||
|
for (Product p : productList) {
|
||||||
|
if (p.getProductName().toLowerCase().contains(lower)
|
||||||
|
|| p.getCategory().toLowerCase().contains(lower)
|
||||||
|
|| p.getProductDesc().toLowerCase().contains(lower)) {
|
||||||
|
filteredList.add(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
adapter.notifyDataSetChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setupSwipeRefresh(View view) {
|
||||||
|
swipeRefreshLayout = view.findViewById(R.id.swipeRefreshProduct);
|
||||||
|
swipeRefreshLayout.setOnRefreshListener(() -> {
|
||||||
|
loadProductData(); // TODO: Replace with actual API call
|
||||||
|
filterProducts(etSearch.getText().toString());
|
||||||
|
swipeRefreshLayout.setRefreshing(false);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void openProductDetails(int position) {
|
||||||
|
ProductDetailFragment detailFragment = new ProductDetailFragment();
|
||||||
|
Bundle args = new Bundle();
|
||||||
|
args.putInt("position", position);
|
||||||
|
|
||||||
|
if (position != -1) {
|
||||||
|
Product product = filteredList.get(position);
|
||||||
|
int realPosition = productList.indexOf(product);
|
||||||
|
args.putInt("position", realPosition);
|
||||||
|
args.putInt("productId", product.getProductId());
|
||||||
|
args.putString("productName", product.getProductName());
|
||||||
|
args.putString("productDesc", product.getProductDesc());
|
||||||
|
args.putString("category", product.getCategory());
|
||||||
|
args.putDouble("productPrice", product.getProductPrice());
|
||||||
|
args.putInt("stockQuantity", product.getStockQuantity());
|
||||||
|
}
|
||||||
|
|
||||||
|
detailFragment.setArguments(args);
|
||||||
|
detailFragment.setProductFragment(this);
|
||||||
|
|
||||||
|
ListFragment listFragment = (ListFragment) getParentFragment();
|
||||||
|
if (listFragment != null) listFragment.loadFragment(detailFragment);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onProductSaved(int position, Product product) {
|
||||||
|
if (position == -1) {
|
||||||
|
productList.add(product);
|
||||||
|
} else {
|
||||||
|
productList.set(position, product);
|
||||||
|
}
|
||||||
|
filterProducts(etSearch.getText().toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onProductDeleted(int position) {
|
||||||
|
productList.remove(position);
|
||||||
|
filterProducts(etSearch.getText().toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onProductClick(int position) {
|
||||||
|
openProductDetails(position);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loadProductData() {
|
||||||
|
productList.clear();
|
||||||
|
productList.add(new Product(1, "Premium Dog Food", "High protein dry food for adult dogs", "Food", 45.99, 25));
|
||||||
|
productList.add(new Product(2, "Cat Toy Bundle", "Set of 5 interactive toys", "Toys", 19.99, 40));
|
||||||
|
productList.add(new Product(3, "Pet Shampoo", "Gentle formula for all breeds", "Grooming", 12.99, 60));
|
||||||
|
productList.add(new Product(4, "Dog Bed - Large", "Memory foam orthopedic bed", "Bedding", 89.99, 10));
|
||||||
|
productList.add(new Product(5, "Aquarium Starter Kit", "20-gallon tank with filter and light", "Aquatic", 129.99, 5));
|
||||||
|
filteredList.clear();
|
||||||
|
filteredList.addAll(productList);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setupRecyclerView(View view) {
|
||||||
|
RecyclerView recyclerView = view.findViewById(R.id.recyclerViewProducts);
|
||||||
|
adapter = new ProductAdapter(filteredList, this);
|
||||||
|
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
|
||||||
|
recyclerView.setAdapter(adapter);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,139 @@
|
|||||||
|
package com.example.petstoremobile.fragments.listfragments.detailfragments;
|
||||||
|
|
||||||
|
// Uses InputValidator for detailed field validation and ActivityLogger to log all changes.
|
||||||
|
|
||||||
|
import android.os.Bundle;
|
||||||
|
import androidx.fragment.app.Fragment;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.Button;
|
||||||
|
import android.widget.EditText;
|
||||||
|
import android.widget.TextView;
|
||||||
|
import android.widget.Toast;
|
||||||
|
import com.example.petstoremobile.R;
|
||||||
|
import com.example.petstoremobile.fragments.ListFragment;
|
||||||
|
import com.example.petstoremobile.fragments.listfragments.ProductFragment;
|
||||||
|
import com.example.petstoremobile.models.Product;
|
||||||
|
import com.example.petstoremobile.utils.ActivityLogger;
|
||||||
|
import com.example.petstoremobile.utils.InputValidator;
|
||||||
|
|
||||||
|
public class ProductDetailFragment extends Fragment {
|
||||||
|
|
||||||
|
private TextView tvMode, tvProductId;
|
||||||
|
private EditText etProductName, etProductDesc, etCategory, etProductPrice, etStockQuantity;
|
||||||
|
private Button btnSaveProduct, btnDeleteProduct, btnBack;
|
||||||
|
private int productId;
|
||||||
|
private int position;
|
||||||
|
private boolean isEditing = false;
|
||||||
|
private ProductFragment productFragment;
|
||||||
|
|
||||||
|
// Set the product fragment as parent so we refer back when save or delete is done
|
||||||
|
public void setProductFragment(ProductFragment fragment) {
|
||||||
|
this.productFragment = fragment;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||||
|
Bundle savedInstanceState) {
|
||||||
|
View view = inflater.inflate(R.layout.fragment_product_detail, container, false);
|
||||||
|
|
||||||
|
initViews(view);
|
||||||
|
handleArguments();
|
||||||
|
|
||||||
|
btnBack.setOnClickListener(v -> {
|
||||||
|
ListFragment listFragment = (ListFragment) getParentFragment();
|
||||||
|
if (listFragment != null) listFragment.getChildFragmentManager().popBackStack();
|
||||||
|
});
|
||||||
|
btnSaveProduct.setOnClickListener(v -> saveProduct());
|
||||||
|
btnDeleteProduct.setOnClickListener(v -> deleteProduct());
|
||||||
|
|
||||||
|
return view;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validates all fields using InputValidator, then saves the product
|
||||||
|
private void saveProduct() {
|
||||||
|
if (!InputValidator.isNotEmpty(etProductName, "Product Name")) return;
|
||||||
|
if (!InputValidator.isNotEmpty(etProductDesc, "Description")) return;
|
||||||
|
if (!InputValidator.isNotEmpty(etCategory, "Category")) return;
|
||||||
|
if (!InputValidator.isPositiveDecimal(etProductPrice, "Price")) return;
|
||||||
|
if (!InputValidator.isPositiveInteger(etStockQuantity, "Stock Quantity")) return;
|
||||||
|
|
||||||
|
String productName = etProductName.getText().toString().trim();
|
||||||
|
String productDesc = etProductDesc.getText().toString().trim();
|
||||||
|
String category = etCategory.getText().toString().trim();
|
||||||
|
double productPrice = Double.parseDouble(etProductPrice.getText().toString().trim());
|
||||||
|
int stockQuantity = Integer.parseInt(etStockQuantity.getText().toString().trim());
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (isEditing) {
|
||||||
|
// TODO: Replace with actual API PUT call when backend is ready
|
||||||
|
Product updated = new Product(productId, productName, productDesc, category, productPrice, stockQuantity);
|
||||||
|
if (productFragment != null) productFragment.onProductSaved(position, updated);
|
||||||
|
ActivityLogger.logChange(requireContext(), "Product", "UPDATED", productId);
|
||||||
|
Toast.makeText(getContext(), "Product updated.", Toast.LENGTH_SHORT).show();
|
||||||
|
} else {
|
||||||
|
// TODO: Replace with actual API POST call when backend is ready
|
||||||
|
Product newProduct = new Product(0, productName, productDesc, category, productPrice, stockQuantity);
|
||||||
|
if (productFragment != null) productFragment.onProductSaved(-1, newProduct);
|
||||||
|
ActivityLogger.log(requireContext(), "Added new Product: " + productName);
|
||||||
|
Toast.makeText(getContext(), "Product added.", Toast.LENGTH_SHORT).show();
|
||||||
|
}
|
||||||
|
ListFragment listFragment = (ListFragment) getParentFragment();
|
||||||
|
if (listFragment != null) listFragment.getChildFragmentManager().popBackStack();
|
||||||
|
} catch (Exception e) {
|
||||||
|
ActivityLogger.logException(requireContext(), "ProductDetailFragment.saveProduct", e);
|
||||||
|
Toast.makeText(getContext(), "Error saving product.", Toast.LENGTH_SHORT).show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deletes the product and logs the action
|
||||||
|
private void deleteProduct() {
|
||||||
|
try {
|
||||||
|
// TODO: Replace with actual API DELETE call when backend is ready
|
||||||
|
if (productFragment != null) productFragment.onProductDeleted(position);
|
||||||
|
ActivityLogger.logChange(requireContext(), "Product", "DELETED", productId);
|
||||||
|
Toast.makeText(getContext(), "Product deleted.", Toast.LENGTH_SHORT).show();
|
||||||
|
ListFragment listFragment = (ListFragment) getParentFragment();
|
||||||
|
if (listFragment != null) listFragment.getChildFragmentManager().popBackStack();
|
||||||
|
} catch (Exception e) {
|
||||||
|
ActivityLogger.logException(requireContext(), "ProductDetailFragment.deleteProduct", e);
|
||||||
|
Toast.makeText(getContext(), "Error deleting product.", Toast.LENGTH_SHORT).show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handleArguments() {
|
||||||
|
if (getArguments() != null && getArguments().containsKey("productId")) {
|
||||||
|
isEditing = true;
|
||||||
|
productId = getArguments().getInt("productId");
|
||||||
|
position = getArguments().getInt("position");
|
||||||
|
tvMode.setText("Edit Product");
|
||||||
|
tvProductId.setText("ID: " + productId);
|
||||||
|
etProductName.setText(getArguments().getString("productName"));
|
||||||
|
etProductDesc.setText(getArguments().getString("productDesc"));
|
||||||
|
etCategory.setText(getArguments().getString("category"));
|
||||||
|
etProductPrice.setText(String.valueOf(getArguments().getDouble("productPrice")));
|
||||||
|
etStockQuantity.setText(String.valueOf(getArguments().getInt("stockQuantity")));
|
||||||
|
btnDeleteProduct.setVisibility(View.VISIBLE);
|
||||||
|
} else {
|
||||||
|
isEditing = false;
|
||||||
|
tvMode.setText("Add Product");
|
||||||
|
tvProductId.setVisibility(View.GONE);
|
||||||
|
btnDeleteProduct.setVisibility(View.GONE);
|
||||||
|
btnSaveProduct.setText("Add");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initViews(View view) {
|
||||||
|
tvMode = view.findViewById(R.id.tvProductMode);
|
||||||
|
tvProductId = view.findViewById(R.id.tvProductId);
|
||||||
|
etProductName = view.findViewById(R.id.etProductName);
|
||||||
|
etProductDesc = view.findViewById(R.id.etProductDesc);
|
||||||
|
etCategory = view.findViewById(R.id.etProductCategory);
|
||||||
|
etProductPrice = view.findViewById(R.id.etProductPrice);
|
||||||
|
etStockQuantity = view.findViewById(R.id.etStockQuantity);
|
||||||
|
btnSaveProduct = view.findViewById(R.id.btnSaveProduct);
|
||||||
|
btnDeleteProduct = view.findViewById(R.id.btnDeleteProduct);
|
||||||
|
btnBack = view.findViewById(R.id.btnProductBack);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,66 @@
|
|||||||
|
package com.example.petstoremobile.models;
|
||||||
|
|
||||||
|
|
||||||
|
public class Product {
|
||||||
|
private int productId;
|
||||||
|
private String productName;
|
||||||
|
private String productDesc;
|
||||||
|
private String category;
|
||||||
|
private double productPrice;
|
||||||
|
private int stockQuantity;
|
||||||
|
|
||||||
|
// Constructor
|
||||||
|
public Product(int productId, String productName, String productDesc, String category, double productPrice, int stockQuantity) {
|
||||||
|
this.productId = productId;
|
||||||
|
this.productName = productName;
|
||||||
|
this.productDesc = productDesc;
|
||||||
|
this.category = category;
|
||||||
|
this.productPrice = productPrice;
|
||||||
|
this.stockQuantity = stockQuantity;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Getters and setters
|
||||||
|
public int getProductId() {
|
||||||
|
return productId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getProductName() {
|
||||||
|
return productName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setProductName(String productName) {
|
||||||
|
this.productName = productName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getProductDesc() {
|
||||||
|
return productDesc;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setProductDesc(String productDesc) {
|
||||||
|
this.productDesc = productDesc;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCategory() {
|
||||||
|
return category;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCategory(String category) {
|
||||||
|
this.category = category;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getProductPrice() {
|
||||||
|
return productPrice;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setProductPrice(double productPrice) {
|
||||||
|
this.productPrice = productPrice;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getStockQuantity() {
|
||||||
|
return stockQuantity;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStockQuantity(int stockQuantity) {
|
||||||
|
this.stockQuantity = stockQuantity;
|
||||||
|
}
|
||||||
|
}
|
||||||
53
app/src/main/res/layout/fragment_product.xml
Normal file
53
app/src/main/res/layout/fragment_product.xml
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
|
||||||
|
<!-- Updated: added search bar and SwipeRefreshLayout for pull-to-refresh -->
|
||||||
|
<androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:background="#F5F5F5">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<EditText
|
||||||
|
android:id="@+id/etSearchProduct"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_margin="8dp"
|
||||||
|
android:hint="Search by product name or category..."
|
||||||
|
android:inputType="text"
|
||||||
|
android:drawableStart="@android:drawable/ic_menu_search"
|
||||||
|
android:drawablePadding="8dp"
|
||||||
|
android:background="@android:color/white"
|
||||||
|
android:padding="12dp"/>
|
||||||
|
|
||||||
|
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
||||||
|
android:id="@+id/swipeRefreshProduct"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
android:id="@+id/recyclerViewProducts"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:padding="8dp"/>
|
||||||
|
|
||||||
|
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||||
|
android:id="@+id/fabAddProduct"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="bottom|end"
|
||||||
|
android:layout_margin="16dp"
|
||||||
|
android:contentDescription="Add Product"
|
||||||
|
app:srcCompat="@android:drawable/ic_input_add"/>
|
||||||
|
|
||||||
|
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||||
|
|
||||||
154
app/src/main/res/layout/fragment_product_detail.xml
Normal file
154
app/src/main/res/layout/fragment_product_detail.xml
Normal file
@@ -0,0 +1,154 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:background="#F5F5F5">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/main"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:paddingLeft="20dp"
|
||||||
|
android:paddingRight="20dp"
|
||||||
|
android:paddingTop="20dp"
|
||||||
|
android:paddingBottom="20dp">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tvProductMode"
|
||||||
|
android:layout_width="245dp"
|
||||||
|
android:layout_height="48dp"
|
||||||
|
android:fontFamily="sans-serif-black"
|
||||||
|
android:text="Add Product"
|
||||||
|
android:textColor="@color/text_dark"
|
||||||
|
android:textSize="25sp" />
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/btnDeleteProduct"
|
||||||
|
android:layout_width="121dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginLeft="20dp"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:text="Delete" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tvProductId"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginBottom="20dp"
|
||||||
|
android:text="ID: 0" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginBottom="4dp"
|
||||||
|
android:text="Product Name"
|
||||||
|
android:textColor="@color/text_dark"
|
||||||
|
android:textSize="12sp" />
|
||||||
|
|
||||||
|
<EditText
|
||||||
|
android:id="@+id/etProductName"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginBottom="16dp"
|
||||||
|
android:hint="Enter product name"
|
||||||
|
android:inputType="text" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginBottom="4dp"
|
||||||
|
android:text="Description"
|
||||||
|
android:textColor="@color/text_dark"
|
||||||
|
android:textSize="12sp" />
|
||||||
|
|
||||||
|
<EditText
|
||||||
|
android:id="@+id/etProductDesc"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginBottom="16dp"
|
||||||
|
android:hint="Enter product description"
|
||||||
|
android:inputType="textMultiLine"
|
||||||
|
android:lines="3" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginBottom="4dp"
|
||||||
|
android:text="Category"
|
||||||
|
android:textColor="@color/text_dark"
|
||||||
|
android:textSize="12sp" />
|
||||||
|
|
||||||
|
<EditText
|
||||||
|
android:id="@+id/etProductCategory"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginBottom="16dp"
|
||||||
|
android:hint="e.g. Food, Toys, Grooming"
|
||||||
|
android:inputType="text" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginBottom="4dp"
|
||||||
|
android:text="Price"
|
||||||
|
android:textColor="@color/text_dark"
|
||||||
|
android:textSize="12sp" />
|
||||||
|
|
||||||
|
<EditText
|
||||||
|
android:id="@+id/etProductPrice"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginBottom="16dp"
|
||||||
|
android:hint="Enter price"
|
||||||
|
android:inputType="numberDecimal" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginBottom="4dp"
|
||||||
|
android:text="Stock Quantity"
|
||||||
|
android:textColor="@color/text_dark"
|
||||||
|
android:textSize="12sp" />
|
||||||
|
|
||||||
|
<EditText
|
||||||
|
android:id="@+id/etStockQuantity"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginBottom="32dp"
|
||||||
|
android:hint="Enter stock quantity"
|
||||||
|
android:inputType="number" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/btnProductBack"
|
||||||
|
android:layout_width="121dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginRight="20dp"
|
||||||
|
android:layout_marginBottom="8dp"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:text="Back" />
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/btnSaveProduct"
|
||||||
|
android:layout_width="121dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginLeft="20dp"
|
||||||
|
android:layout_marginBottom="8dp"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:text="Save" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
</ScrollView>
|
||||||
Reference in New Issue
Block a user