From 71d24ef9ddaa97d5ec67c3aceb9c36a2638f9684 Mon Sep 17 00:00:00 2001 From: Nezumi <123229563+Nez27@users.noreply.github.com> Date: Thu, 2 Mar 2023 17:26:43 +0700 Subject: [PATCH] Swipe to delete in favorite screen --- .../foodify/Fragment/FavouriteFragment.java | 76 ++++++++++- .../foodify/ItemTouchHelperListener.java | 8 ++ .../com/capstone/foodify/Model/Food/Food.java | 16 +++ .../Model/Food/FoodFavoriteAdapter.java | 81 +++++++++++ .../foodify/RecyclerViewItemTouchHelper.java | 60 +++++++++ .../main/res/drawable/baseline_delete_24.xml | 5 + .../main/res/layout/fragment_favourite.xml | 6 +- .../main/res/layout/item_food_favorite.xml | 126 ++++++++++++++++++ .../main/res/layout/item_food_horizontal.xml | 120 ----------------- app/src/main/res/values/strings.xml | 1 + 10 files changed, 375 insertions(+), 124 deletions(-) create mode 100644 app/src/main/java/com/capstone/foodify/ItemTouchHelperListener.java create mode 100644 app/src/main/java/com/capstone/foodify/Model/Food/FoodFavoriteAdapter.java create mode 100644 app/src/main/java/com/capstone/foodify/RecyclerViewItemTouchHelper.java create mode 100644 app/src/main/res/drawable/baseline_delete_24.xml create mode 100644 app/src/main/res/layout/item_food_favorite.xml delete mode 100644 app/src/main/res/layout/item_food_horizontal.xml diff --git a/app/src/main/java/com/capstone/foodify/Fragment/FavouriteFragment.java b/app/src/main/java/com/capstone/foodify/Fragment/FavouriteFragment.java index 57e8167..0cbe6c4 100644 --- a/app/src/main/java/com/capstone/foodify/Fragment/FavouriteFragment.java +++ b/app/src/main/java/com/capstone/foodify/Fragment/FavouriteFragment.java @@ -1,20 +1,92 @@ package com.capstone.foodify.Fragment; +import android.graphics.Color; import android.os.Bundle; +import androidx.core.widget.NestedScrollView; import androidx.fragment.app.Fragment; +import androidx.recyclerview.widget.DividerItemDecoration; +import androidx.recyclerview.widget.ItemTouchHelper; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import com.capstone.foodify.ItemTouchHelperListener; +import com.capstone.foodify.Model.Food.Food; +import com.capstone.foodify.Model.Food.FoodFavoriteAdapter; import com.capstone.foodify.R; +import com.capstone.foodify.RecyclerViewItemTouchHelper; +import com.google.android.material.snackbar.Snackbar; -public class FavouriteFragment extends Fragment { +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +public class FavouriteFragment extends Fragment implements ItemTouchHelperListener { + + private RecyclerView recyclerView_favorite_food; + private FoodFavoriteAdapter adapter; + private List listFavoriteFood = new ArrayList<>(); + + private NestedScrollView listFavoriteFoodView; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // Inflate the layout for this fragment - return inflater.inflate(R.layout.fragment_favourite, container, false); + View rootView = inflater.inflate(R.layout.fragment_favourite, container, false); + + recyclerView_favorite_food = rootView.findViewById(R.id.recycler_view_favorite_food); + listFavoriteFoodView = rootView.findViewById(R.id.list_favorite_food_view); + + LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getContext()); + recyclerView_favorite_food.setLayoutManager(linearLayoutManager); + + listFavoriteFood = getListFavoriteFood(); + adapter = new FoodFavoriteAdapter(getListFavoriteFood()); + recyclerView_favorite_food.setAdapter(adapter); + + RecyclerView.ItemDecoration itemDecoration = new DividerItemDecoration(requireContext(), DividerItemDecoration.VERTICAL); + recyclerView_favorite_food.addItemDecoration(itemDecoration); + + ItemTouchHelper.SimpleCallback simpleCallback = new RecyclerViewItemTouchHelper(0, ItemTouchHelper.LEFT, this); + new ItemTouchHelper(simpleCallback).attachToRecyclerView(recyclerView_favorite_food); + return rootView; + } + + private List getListFavoriteFood() { + List listFoodTemp = new ArrayList<>(); + + for(int i = 1; i <= 20; i++){ + listFoodTemp.add(new Food(String.valueOf(i), "https://cdn.netspace.edu.vn/images/2022/09/29/hoc-nau-mi-quang-1-1024.jpg", "Food "+ i, "25000", "Shop " + i)); + } + + return listFoodTemp; + } + + @Override + public void onSwiped(RecyclerView.ViewHolder viewHolder) { + if(viewHolder instanceof FoodFavoriteAdapter.FoodFavoriteViewHolder){ + String foodNameDelete = listFavoriteFood.get(viewHolder.getAdapterPosition()).getName(); + + Food foodDelete = listFavoriteFood.get(viewHolder.getAdapterPosition()); + int indexDelete = viewHolder.getAdapterPosition(); + + //Remove Item + adapter.removeItem(indexDelete); + + //Show notification food has been delete + Snackbar snackbar = Snackbar.make(listFavoriteFoodView, foodNameDelete + "remove!", Snackbar.LENGTH_LONG); + snackbar.setAction("Undo", new View.OnClickListener() { + @Override + public void onClick(View view) { + adapter.undoItem(foodDelete, indexDelete); + } + }); + snackbar.setActionTextColor(Color.YELLOW); + snackbar.show(); + } } } \ No newline at end of file diff --git a/app/src/main/java/com/capstone/foodify/ItemTouchHelperListener.java b/app/src/main/java/com/capstone/foodify/ItemTouchHelperListener.java new file mode 100644 index 0000000..151d7f5 --- /dev/null +++ b/app/src/main/java/com/capstone/foodify/ItemTouchHelperListener.java @@ -0,0 +1,8 @@ +package com.capstone.foodify; + +import androidx.recyclerview.widget.RecyclerView; + +public interface ItemTouchHelperListener { + + void onSwiped(RecyclerView.ViewHolder viewHolder); +} diff --git a/app/src/main/java/com/capstone/foodify/Model/Food/Food.java b/app/src/main/java/com/capstone/foodify/Model/Food/Food.java index 177b485..518d1e4 100644 --- a/app/src/main/java/com/capstone/foodify/Model/Food/Food.java +++ b/app/src/main/java/com/capstone/foodify/Model/Food/Food.java @@ -8,6 +8,7 @@ public class Food { private String discount; private String description; + private String shopName; private String reviewCount; public String getReviewCount() { @@ -21,6 +22,14 @@ public class Food { public Food() { } + public Food(String id, String img, String name, String price, String shopName) { + this.id = id; + this.img = img; + this.name = name; + this.price = price; + this.shopName = shopName; + } + public String getId() { return id; } @@ -68,4 +77,11 @@ public class Food { public void setDescription(String description) { this.description = description; } + public String getShopName() { + return shopName; + } + + public void setShopName(String shopName) { + this.shopName = shopName; + } } diff --git a/app/src/main/java/com/capstone/foodify/Model/Food/FoodFavoriteAdapter.java b/app/src/main/java/com/capstone/foodify/Model/Food/FoodFavoriteAdapter.java new file mode 100644 index 0000000..f0c73ee --- /dev/null +++ b/app/src/main/java/com/capstone/foodify/Model/Food/FoodFavoriteAdapter.java @@ -0,0 +1,81 @@ +package com.capstone.foodify.Model.Food; + +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.cardview.widget.CardView; +import androidx.recyclerview.widget.RecyclerView; + +import com.capstone.foodify.R; +import com.squareup.picasso.Picasso; + +import java.util.List; + +public class FoodFavoriteAdapter extends RecyclerView.Adapter { + + private List listFavoriteFood; + + public FoodFavoriteAdapter(List listFavoriteFood) { + this.listFavoriteFood = listFavoriteFood; + } + @NonNull + @Override + public FoodFavoriteViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_food_favorite, parent, false); + return new FoodFavoriteViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull FoodFavoriteViewHolder holder, int position) { + Food food = listFavoriteFood.get(position); + + if(food == null) + return; + + holder.foodName.setText(food.getName()); + holder.shopName.setText(food.getShopName()); + holder.price.setText(food.getPrice()); + Picasso.get().load(food.getImg()).into(holder.imageView); + } + + @Override + public int getItemCount() { + if(listFavoriteFood != null) + return listFavoriteFood.size(); + + return 0; + } + + public static class FoodFavoriteViewHolder extends RecyclerView.ViewHolder{ + + TextView foodName, shopName, price; + public LinearLayout layoutForeGround; + ImageView imageView; + + public FoodFavoriteViewHolder(@NonNull View itemView) { + super(itemView); + + foodName = itemView.findViewById(R.id.food_name_text_view); + shopName = itemView.findViewById(R.id.shop_name_text_view); + price = itemView.findViewById(R.id.price_text_view); + imageView = itemView.findViewById(R.id.image_view); + + layoutForeGround = itemView.findViewById(R.id.layout_foreground); + } + } + + public void removeItem(int index){ + listFavoriteFood.remove(index); + notifyItemRemoved(index); + } + + public void undoItem(Food food, int index){ + listFavoriteFood.add(index, food); + notifyItemInserted(index); + } +} diff --git a/app/src/main/java/com/capstone/foodify/RecyclerViewItemTouchHelper.java b/app/src/main/java/com/capstone/foodify/RecyclerViewItemTouchHelper.java new file mode 100644 index 0000000..400da46 --- /dev/null +++ b/app/src/main/java/com/capstone/foodify/RecyclerViewItemTouchHelper.java @@ -0,0 +1,60 @@ +package com.capstone.foodify; + +import android.graphics.Canvas; +import android.view.View; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.recyclerview.widget.ItemTouchHelper; +import androidx.recyclerview.widget.RecyclerView; + +import com.capstone.foodify.Model.Food.FoodFavoriteAdapter; + +public class RecyclerViewItemTouchHelper extends ItemTouchHelper.SimpleCallback{ + + private ItemTouchHelperListener listener; + + public RecyclerViewItemTouchHelper(int dragDirs, int swipeDirs, ItemTouchHelperListener listener) { + super(dragDirs, swipeDirs); + this.listener = listener; + } + + @Override + public boolean onMove(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, @NonNull RecyclerView.ViewHolder target) { + return true; + } + + @Override + public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int direction) { + if(listener != null) + listener.onSwiped(viewHolder); + } + + @Override + public void onSelectedChanged(@Nullable RecyclerView.ViewHolder viewHolder, int actionState) { + if(viewHolder != null){ + View foreGroundView = ((FoodFavoriteAdapter.FoodFavoriteViewHolder) viewHolder).layoutForeGround; + getDefaultUIUtil().onSelected(foreGroundView); + } + + } + + @Override + public void onChildDrawOver(@NonNull Canvas c, @NonNull RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) { + assert viewHolder != null; + View foreGroundView = ((FoodFavoriteAdapter.FoodFavoriteViewHolder) viewHolder).layoutForeGround; + getDefaultUIUtil().onDrawOver(c, recyclerView, foreGroundView, dX, dY, actionState, isCurrentlyActive); + } + + @Override + public void onChildDraw(@NonNull Canvas c, @NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) { + View foreGroundView = ((FoodFavoriteAdapter.FoodFavoriteViewHolder) viewHolder).layoutForeGround; + getDefaultUIUtil().onDraw(c, recyclerView, foreGroundView, dX, dY, actionState, isCurrentlyActive); + } + + @Override + public void clearView(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder) { + View foreGroundView = ((FoodFavoriteAdapter.FoodFavoriteViewHolder) viewHolder).layoutForeGround; + getDefaultUIUtil().clearView(foreGroundView); + } +} diff --git a/app/src/main/res/drawable/baseline_delete_24.xml b/app/src/main/res/drawable/baseline_delete_24.xml new file mode 100644 index 0000000..5be5b88 --- /dev/null +++ b/app/src/main/res/drawable/baseline_delete_24.xml @@ -0,0 +1,5 @@ + + + diff --git a/app/src/main/res/layout/fragment_favourite.xml b/app/src/main/res/layout/fragment_favourite.xml index 833a4ed..8bce226 100644 --- a/app/src/main/res/layout/fragment_favourite.xml +++ b/app/src/main/res/layout/fragment_favourite.xml @@ -4,7 +4,9 @@ android:layout_width="match_parent" android:layout_height="match_parent" xmlns:app="http://schemas.android.com/apk/res-auto" - tools:context=".Fragment.FavouriteFragment"> + tools:context=".Fragment.FavouriteFragment" + android:id="@+id/list_favorite_food_view" + > + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_food_horizontal.xml b/app/src/main/res/layout/item_food_horizontal.xml deleted file mode 100644 index 9fb3204..0000000 --- a/app/src/main/res/layout/item_food_horizontal.xml +++ /dev/null @@ -1,120 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 0f6be95..71aa38f 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -46,4 +46,5 @@ Mật khẩu cũ Đổi mật khẩu Thông tin tài khoản + Delete \ No newline at end of file