Add favorite food

This commit is contained in:
Nezumi
2023-03-16 17:59:33 +07:00
parent 17ce01ce4f
commit ebd313e32c
7 changed files with 300 additions and 112 deletions
+3 -1
View File
@@ -30,7 +30,9 @@
tools:targetApi="31">
<activity
android:name=".Activity.FavoriteFoodActivity"
android:exported="false" />
android:exported="false"
android:noHistory="true"
/>
<activity
android:name=".Activity.ShopDetailActivity"
android:exported="false" />
@@ -1,37 +1,59 @@
package com.capstone.foodify.Activity;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.core.widget.NestedScrollView;
import androidx.recyclerview.widget.DividerItemDecoration;
import androidx.recyclerview.widget.ItemTouchHelper;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.app.Dialog;
import android.content.Intent;
import android.graphics.Color;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
import com.capstone.foodify.API.FoodApiToken;
import com.capstone.foodify.Adapter.FoodFavoriteAdapter;
import com.capstone.foodify.Adapter.RecyclerViewItemTouchHelperFavoriteFood;
import com.capstone.foodify.Common;
import com.capstone.foodify.ItemTouchHelperListener;
import com.capstone.foodify.Model.Food;
import com.capstone.foodify.Model.Response.Foods;
import com.capstone.foodify.R;
import com.google.android.material.snackbar.Snackbar;
import com.saadahmedsoft.popupdialog.PopupDialog;
import com.saadahmedsoft.popupdialog.Styles;
import com.saadahmedsoft.popupdialog.listener.OnDialogButtonClickListener;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class FavoriteFoodActivity extends AppCompatActivity implements ItemTouchHelperListener {
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
public class FavoriteFoodActivity extends AppCompatActivity implements ItemTouchHelperListener {
private static int CURRENT_PAGE = 0;
private static final int PAGE_SIZE = 8;
private static final String SORT_BY = "name";
private static final String SORT_DIR = "asc";
private static boolean LAST_PAGE;
private RecyclerView recyclerView_favorite_food;
private FoodFavoriteAdapter adapter;
private final List<Food> listFavoriteFood = new ArrayList<>();
private ImageView back_image;
private NestedScrollView listFavoriteFoodView;
private ConstraintLayout listFavoriteFoodView, progressLayout;
private NestedScrollView nestedScrollView;
private ProgressBar progressBar;
private TextView endOfListText;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -39,6 +61,24 @@ public class FavoriteFoodActivity extends AppCompatActivity implements ItemTouch
//Init component
back_image = findViewById(R.id.back_image);
progressLayout = findViewById(R.id.progress_layout);
nestedScrollView = findViewById(R.id.nestedScrollView);
progressBar = findViewById(R.id.progress_bar);
endOfListText = findViewById(R.id.end_of_list_text);
//Set event when user scroll down
if (nestedScrollView != null) {
nestedScrollView.setOnScrollChangeListener(new NestedScrollView.OnScrollChangeListener() {
@Override
public void onScrollChange(@NonNull NestedScrollView v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {
if (scrollY == (v.getChildAt(0).getMeasuredHeight() - v.getMeasuredHeight())) {
//When user scroll to bottom, load more data
dataLoadMore();
}
}
});
}
//Set event for back image
back_image.setOnClickListener(new View.OnClickListener() {
@@ -56,12 +96,12 @@ public class FavoriteFoodActivity extends AppCompatActivity implements ItemTouch
listFavoriteFoodView = findViewById(R.id.list_favorite_food_view);
//Get list favorite food
getListFavoriteFood();
getListFavoriteFood(CURRENT_PAGE);
//Set layout recyclerview
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
recyclerView_favorite_food.setLayoutManager(linearLayoutManager);
adapter = new FoodFavoriteAdapter();
adapter = new FoodFavoriteAdapter(this);
RecyclerView.ItemDecoration itemDecoration = new DividerItemDecoration(this, DividerItemDecoration.VERTICAL);
recyclerView_favorite_food.addItemDecoration(itemDecoration);
@@ -70,38 +110,47 @@ public class FavoriteFoodActivity extends AppCompatActivity implements ItemTouch
new ItemTouchHelper(simpleCallback).attachToRecyclerView(recyclerView_favorite_food);
}
private void getListFavoriteFood() {
//Get data from api
// FoodApiToken.apiService.getListFavoriteFood().enqueue(new Callback<List<Food>>() {
// @Override
// public void onResponse(@NonNull Call<List<Food>> call, @NonNull Response<List<Food>> response) {
// List<Food> listFoodData = response.body();
// if(listFoodData != null){
// listFavoriteFood.addAll(listFoodData);
// }
// Collections.sort(listFavoriteFood);
//
// adapter.setData(listFavoriteFood);
// recyclerView_favorite_food.setAdapter(adapter);
// }
//
// @Override
// public void onFailure(Call<List<Food>> call, Throwable t) {
// //Check internet connection
// if(Common.checkInternetConnection(getContext())){
// //Has internet connection
// Toast.makeText(getContext(), "Error: " + t, Toast.LENGTH_SHORT).show();
// } else {
// //No internet, show notification
// Common.showErrorInternetConnectionNotification(getActivity());
//
// Log.e("ERROR", "Get list favorite food error!");
//
// }
// }
// });
private void dataLoadMore() {
if(!LAST_PAGE){
getListFavoriteFood(++CURRENT_PAGE);
} else {
progressBar.setVisibility(View.GONE);
endOfListText.setVisibility(View.VISIBLE);
}
}
private void getListFavoriteFood(int page) {
//Get data from api
FoodApiToken.apiService.getListFavoriteFood(Common.CURRENT_USER.getId(), page, PAGE_SIZE, SORT_BY, SORT_DIR).enqueue(new Callback<Foods>() {
@Override
public void onResponse(Call<Foods> call, Response<Foods> response) {
//Dismiss progress
progressLayout.setVisibility(View.GONE);
Foods foodData = response.body();
if(foodData != null){
listFavoriteFood.addAll(foodData.getProducts());
LAST_PAGE = foodData.getPage().isLast();
}
Collections.sort(listFavoriteFood);
adapter.setData(listFavoriteFood);
recyclerView_favorite_food.setAdapter(adapter);
}
@Override
public void onFailure(Call<Foods> call, Throwable t) {
Toast.makeText(FavoriteFoodActivity.this, "Đã có lỗi từ hệ thống! Vui lòng thử lại sau!", Toast.LENGTH_SHORT).show();
}
});
}
@Override
public void onSwiped(RecyclerView.ViewHolder viewHolder) {
if(viewHolder instanceof FoodFavoriteAdapter.FoodFavoriteViewHolder){
@@ -111,7 +160,7 @@ public class FavoriteFoodActivity extends AppCompatActivity implements ItemTouch
int indexDelete = viewHolder.getAdapterPosition();
//Remove Item
adapter.removeItem(indexDelete, this);
adapter.removeItem(foodDelete, indexDelete, this);
//Show notification food has been delete
Snackbar snackbar = Snackbar.make(listFavoriteFoodView, foodNameDelete + " remove!", Snackbar.LENGTH_LONG);
@@ -56,7 +56,13 @@ public class FoodAdapter extends RecyclerView.Adapter<FoodAdapter.FoodViewHolder
} else {
holder.name.setText(foodName);
}
Picasso.get().load(food.getImages().get(0).getImageUrl()).into(holder.image);
//When food does not have image
if(food.getImages().size() == 0){
holder.image.setImageResource(R.drawable.default_image_food);
} else {
Picasso.get().load(food.getImages().get(0).getImageUrl()).into(holder.image);
}
//Check value discountPercent
float cost = 0;
@@ -13,8 +13,12 @@ import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.capstone.foodify.API.FoodApiToken;
import com.capstone.foodify.Activity.FoodDetailActivity;
import com.capstone.foodify.Common;
import com.capstone.foodify.Model.Basket;
import com.capstone.foodify.Model.Food;
import com.capstone.foodify.R;
import com.squareup.picasso.Picasso;
import java.util.List;
@@ -25,8 +29,11 @@ import retrofit2.Response;
public class FoodFavoriteAdapter extends RecyclerView.Adapter<FoodFavoriteAdapter.FoodFavoriteViewHolder> {
private List<Food> listFavoriteFood;
private Context context;
public FoodFavoriteAdapter(){}
public FoodFavoriteAdapter(Context context){
this.context = context;
}
public void setData(List<Food> listFavoriteFood){
this.listFavoriteFood = listFavoriteFood;
@@ -45,10 +52,67 @@ public class FoodFavoriteAdapter extends RecyclerView.Adapter<FoodFavoriteAdapt
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);
holder.foodName.setText(food.getName());
holder.shopName.setText(food.getShop().getName());
//Check value discountPercent
float cost = 0;
if(food.getDiscountPercent() > 0){
//Calculate final cost when apply discountPercent
cost = food.getCost() - (food.getCost() * food.getDiscountPercent()/100);
//Show discountPercent value on screen
holder.discount.setVisibility(View.VISIBLE);
holder.discount.setText("-" + food.getDiscountPercent()+ "%");
} else {
cost = food.getCost();
}
holder.price.setText(Common.changeCurrencyUnit(cost));
//When food does not have image
if(food.getImages().size() == 0){
holder.imageView.setImageResource(R.drawable.default_image_food);
} else {
Picasso.get().load(food.getImages().get(0).getImageUrl()).into(holder.imageView);
}
//Set event basket icon
holder.basket_icon.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Basket foodInBasket = Common.getFoodExistInBasket(food.getId());
if(foodInBasket == null){
//If item is not exist in basket
//Check food image is null or not
String imageTemp = null;
if(food.getImages().size() > 0)
imageTemp = food.getImages().get(0).getImageUrl();
Common.LIST_BASKET_FOOD.add(new Basket(food.getId(), imageTemp, food.getName(), food.getCost(), food.getShop().getName(),
"1", food.getDiscountPercent()));
} else {
//If item is exist in basket
for(int i = 0; i < Common.LIST_BASKET_FOOD.size(); i++){
String foodId = Common.LIST_BASKET_FOOD.get(i).getId();
//Find foodId exist
if(foodId.equals(food.getId())){
//Get quantity food from basket
String quantity = Common.LIST_BASKET_FOOD.get(i).getQuantity();
//Change quantity food from basket
int quantityInt = Integer.parseInt(quantity) + 1;
Common.LIST_BASKET_FOOD.get(i).setQuantity(String.valueOf(quantityInt));
break;
}
}
}
Toast.makeText(context, "Đã thêm " + food.getName() + " vào giỏ hàng!", Toast.LENGTH_SHORT).show();
}
});
}
@Override
@@ -61,9 +125,9 @@ public class FoodFavoriteAdapter extends RecyclerView.Adapter<FoodFavoriteAdapt
public static class FoodFavoriteViewHolder extends RecyclerView.ViewHolder{
TextView foodName, shopName, price;
TextView foodName, shopName, price, discount;
public LinearLayout layoutForeGround;
ImageView imageView;
ImageView imageView, basket_icon;
public FoodFavoriteViewHolder(@NonNull View itemView) {
super(itemView);
@@ -72,42 +136,45 @@ public class FoodFavoriteAdapter extends RecyclerView.Adapter<FoodFavoriteAdapt
shopName = itemView.findViewById(R.id.shop_name_text_view);
price = itemView.findViewById(R.id.price_text_view);
imageView = itemView.findViewById(R.id.image_view);
discount = itemView.findViewById(R.id.discount);
basket_icon = itemView.findViewById(R.id.basket_icon);
layoutForeGround = itemView.findViewById(R.id.layout_foreground);
}
}
public void removeItem(int index, Context context){
public void removeItem(Food food, int index, Context context){
listFavoriteFood.remove(index);
notifyItemRemoved(index);
// FoodApiToken.apiService.removeFoodFromFavorite(index).enqueue(new Callback<Food>() {
// @Override
// public void onResponse(Call<Food> call, Response<Food> response) {
// Toast.makeText(context, "Remove successful!", Toast.LENGTH_SHORT).show();
// }
//
// @Override
// public void onFailure(Call<Food> call, Throwable t) {
// Toast.makeText(context, "Error: " + t, Toast.LENGTH_SHORT).show();
// }
// });
FoodApiToken.apiService.removeFoodFromFavorite(Common.CURRENT_USER.getId(), Integer.parseInt(food.getId())).enqueue(new Callback<Food>() {
@Override
public void onResponse(Call<Food> call, Response<Food> response) {
Toast.makeText(context, "Đã xoá " + food.getName() + " khỏi danh sách yêu thích!", Toast.LENGTH_SHORT).show();
}
@Override
public void onFailure(Call<Food> call, Throwable t) {
Toast.makeText(context, "Oops! Đã có lỗi, vui lòng thử lại sau!", Toast.LENGTH_SHORT).show();
}
});
}
public void undoItem(Food food, int index, Context context){
listFavoriteFood.add(index, food);
notifyItemInserted(index);
// FoodApiToken.apiService.addFoodToFavorite(food.getId()).enqueue(new Callback<Food>() {
// @Override
// public void onResponse(@NonNull Call<Food> call, @NonNull Response<Food> response) {
// Toast.makeText(context, "Add successful!", Toast.LENGTH_SHORT).show();
// }
//
// @Override
// public void onFailure(@NonNull Call<Food> call, @NonNull Throwable t) {
// Toast.makeText(context, "Error: " + t, Toast.LENGTH_SHORT).show();
// }
// });
FoodApiToken.apiService.addFoodToFavorite(Common.CURRENT_USER.getId(), Integer.parseInt(food.getId())).enqueue(new Callback<Food>() {
@Override
public void onResponse(Call<Food> call, Response<Food> response) {
Toast.makeText(context, "Đã thêm " + food.getName() + " vào danh sách yêu thích!", Toast.LENGTH_SHORT).show();
}
@Override
public void onFailure(Call<Food> call, Throwable t) {
Toast.makeText(context, "Oops! Đã có lỗi, vui lòng thử lại sau!", Toast.LENGTH_SHORT).show();
}
});
}
}
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.core.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
@@ -8,47 +8,95 @@
android:id="@+id/list_favorite_food_view"
>
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/nestedScrollView"
>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/back_image"
android:layout_width="20dp"
android:layout_height="20dp"
android:src="@drawable/back_button"
android:layout_marginStart="10dp"
android:layout_marginTop="25dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/text_view_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Favourite Food"
android:fontFamily="@font/bebas"
android:textColor="@color/black"
android:textSize="40sp"
android:layout_marginTop="20dp"
android:layout_marginStart="10dp"
app:layout_constraintTop_toBottomOf="@id/back_image"
app:layout_constraintStart_toStartOf="parent"
/>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_view_favorite_food"
tools:listitem="@layout/item_food_search_and_favorite"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="15dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/text_view_1"
/>
<ProgressBar
android:id="@+id/progress_bar"
android:indeterminateTint="@color/primaryColor"
app:layout_constraintTop_toBottomOf="@id/recycler_view_favorite_food"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
<TextView
android:id="@+id/end_of_list_text"
android:text="End of list"
android:fontFamily="@font/opensans"
android:textColor="@color/grayLight"
android:visibility="gone"
app:layout_constraintTop_toBottomOf="@id/progress_bar"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.core.widget.NestedScrollView>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
android:layout_height="match_parent"
android:background="#80000000"
android:id="@+id/progress_layout"
>
<ImageView
android:id="@+id/back_image"
android:layout_width="20dp"
android:layout_height="20dp"
android:src="@drawable/back_button"
android:layout_marginStart="10dp"
android:layout_marginTop="25dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/text_view_1"
<ProgressBar
android:id="@+id/progressBarLoadData"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Favourite Food"
android:fontFamily="@font/bebas"
android:textColor="@color/black"
android:textSize="40sp"
android:layout_marginTop="20dp"
android:layout_marginStart="10dp"
app:layout_constraintTop_toBottomOf="@id/back_image"
android:indeterminateTint="@color/primaryColor"
app:layout_constraintStart_toStartOf="parent"
/>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_view_favorite_food"
tools:listitem="@layout/item_food_favorite"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="15dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/text_view_1"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
/>
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.core.widget.NestedScrollView>
</androidx.constraintlayout.widget.ConstraintLayout>
+1 -1
View File
@@ -48,7 +48,7 @@
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_view_search"
tools:listitem="@layout/item_food_search"
tools:listitem="@layout/item_food_search_and_favorite"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="@id/list_category"
+25 -9
View File
@@ -92,17 +92,33 @@
app:layout_constraintTop_toBottomOf="@id/text_view_1"
/>
<TextView
android:id="@+id/price_text_view"
android:text="$5.00"
android:textSize="25sp"
android:textColor="@color/primaryColor"
android:fontFamily="@font/bebas"
android:layout_width="220dp"
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:layout_marginTop="2dp"
/>
>
<TextView
android:id="@+id/price_text_view"
android:text="$5.00"
android:textSize="25sp"
android:textColor="@color/primaryColor"
android:fontFamily="@font/bebas"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
/>
<TextView
android:id="@+id/discount"
android:text="-59%"
android:textSize="8sp"
android:textColor="@color/red"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:visibility="gone"
/>
</LinearLayout>
</LinearLayout>
<LinearLayout