diff --git a/app/build.gradle b/app/build.gradle index 2c122c2..20f7b22 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -49,4 +49,6 @@ dependencies { implementation 'com.github.smarteist:autoimageslider:1.4.0' implementation 'com.github.bumptech.glide:glide:4.14.2' annotationProcessor 'com.github.bumptech.glide:compiler:4.14.2' + + implementation 'com.squareup.picasso:picasso:2.8' } \ No newline at end of file diff --git a/app/src/main/java/com/capstone/foodify/API/ApiService.java b/app/src/main/java/com/capstone/foodify/API/DistrictWardApi.java similarity index 79% rename from app/src/main/java/com/capstone/foodify/API/ApiService.java rename to app/src/main/java/com/capstone/foodify/API/DistrictWardApi.java index 2d1d527..92ee002 100644 --- a/app/src/main/java/com/capstone/foodify/API/ApiService.java +++ b/app/src/main/java/com/capstone/foodify/API/DistrictWardApi.java @@ -1,6 +1,6 @@ package com.capstone.foodify.API; -import com.capstone.foodify.DistrictWardResponse.DisctrictWardResponse; +import com.capstone.foodify.Model.DistrictWard.DisctrictWardResponse; import com.google.gson.Gson; import com.google.gson.GsonBuilder; @@ -11,14 +11,14 @@ import retrofit2.http.GET; import retrofit2.http.Query; -public interface ApiService { +public interface DistrictWardApi { Gson gson = new GsonBuilder().setDateFormat("HH:mm:ss dd-MM-yyyy").create(); - ApiService apiService = new Retrofit.Builder() + DistrictWardApi apiService = new Retrofit.Builder() .baseUrl("https://vn-public-apis.fpo.vn/").addConverterFactory(GsonConverterFactory.create(gson)) .build() - .create(ApiService.class); + .create(DistrictWardApi.class); @GET("wards/getByDistrict") Call wardResponse(@Query("districtCode") int districtCode, @Query("limit") int limit); diff --git a/app/src/main/java/com/capstone/foodify/API/FoodApi.java b/app/src/main/java/com/capstone/foodify/API/FoodApi.java new file mode 100644 index 0000000..3ba8f06 --- /dev/null +++ b/app/src/main/java/com/capstone/foodify/API/FoodApi.java @@ -0,0 +1,29 @@ +package com.capstone.foodify.API; + +import com.capstone.foodify.Model.Food.Food; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; + +import java.util.List; + +import retrofit2.Call; +import retrofit2.Retrofit; +import retrofit2.converter.gson.GsonConverterFactory; +import retrofit2.http.GET; + + +public interface FoodApi { + + Gson gson = new GsonBuilder().setDateFormat("HH:mm:ss dd-MM-yyyy").create(); + + FoodApi apiService = new Retrofit.Builder() + .baseUrl("https://free-food-menus-api-production.up.railway.app/").addConverterFactory(GsonConverterFactory.create(gson)) + .build() + .create(FoodApi.class); + + @GET("best-foods") + Call> bestFoodResponse(); + + @GET("drinks") + Call> drinksFoodResponse(); +} diff --git a/app/src/main/java/com/capstone/foodify/Activity/SignUpActivity.java b/app/src/main/java/com/capstone/foodify/Activity/SignUpActivity.java index 616cfe6..6e0600e 100644 --- a/app/src/main/java/com/capstone/foodify/Activity/SignUpActivity.java +++ b/app/src/main/java/com/capstone/foodify/Activity/SignUpActivity.java @@ -18,9 +18,9 @@ import android.widget.Spinner; import android.widget.TextView; import android.widget.Toast; -import com.capstone.foodify.API.ApiService; -import com.capstone.foodify.DistrictWardResponse.Datas; -import com.capstone.foodify.DistrictWardResponse.DisctrictWardResponse; +import com.capstone.foodify.API.DistrictWardApi; +import com.capstone.foodify.Model.DistrictWard.Datas; +import com.capstone.foodify.Model.DistrictWard.DisctrictWardResponse; import com.capstone.foodify.R; import com.google.android.material.textfield.TextInputLayout; @@ -134,7 +134,7 @@ public class SignUpActivity extends AppCompatActivity { districtList.add("---Quận"); - ApiService.apiService.districtResponse(PROVINCE_CODE, LIMIT).enqueue(new Callback() { + DistrictWardApi.apiService.districtResponse(PROVINCE_CODE, LIMIT).enqueue(new Callback() { @Override public void onResponse(Call call, Response response) { DisctrictWardResponse districtResponse = response.body(); @@ -165,7 +165,7 @@ public class SignUpActivity extends AppCompatActivity { wardList.add("---Phường"); if(districtCode != 0){ - ApiService.apiService.wardResponse(districtCode, LIMIT).enqueue(new Callback() { + DistrictWardApi.apiService.wardResponse(districtCode, LIMIT).enqueue(new Callback() { @Override public void onResponse(Call call, Response response) { diff --git a/app/src/main/java/com/capstone/foodify/Fragment/HomeFragment.java b/app/src/main/java/com/capstone/foodify/Fragment/HomeFragment.java index 9fc5fe4..05e1742 100644 --- a/app/src/main/java/com/capstone/foodify/Fragment/HomeFragment.java +++ b/app/src/main/java/com/capstone/foodify/Fragment/HomeFragment.java @@ -4,9 +4,16 @@ import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.widget.Toast; import androidx.fragment.app.Fragment; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; +import com.capstone.foodify.API.FoodApi; +import com.capstone.foodify.Model.Food.Food; +import com.capstone.foodify.Model.Menu.Menu; +import com.capstone.foodify.Model.Menu.MenuAdapter; import com.capstone.foodify.R; import com.denzcoskun.imageslider.ImageSlider; import com.denzcoskun.imageslider.constants.ScaleTypes; @@ -14,19 +21,40 @@ import com.denzcoskun.imageslider.models.SlideModel; import java.util.ArrayList; import java.util.List; +import java.util.concurrent.CompletableFuture; + +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Response; public class HomeFragment extends Fragment { - ImageSlider imageSlider; + private static List listFood = new ArrayList<>(); + private static List drinkFood = new ArrayList<>(); + + private ImageSlider imageSlider; + + private RecyclerView rcvMenu; + private MenuAdapter menuAdapter; + + @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment_home, container, false); + //Init Component imageSlider = (ImageSlider) view.findViewById(R.id.slider); + rcvMenu = view.findViewById(R.id.recycler_view_menu); + menuAdapter = new MenuAdapter(getContext()); + + getListFood(); + drinkListFood(); + + LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getContext(), RecyclerView.VERTICAL, false); + rcvMenu.setLayoutManager(linearLayoutManager); List slideModels = new ArrayList<>(); - slideModels.add(new SlideModel("https://res.cloudinary.com/dnkmxpujh/image/upload/v1676023773/banner1_dandvd.png", null)); slideModels.add(new SlideModel("https://res.cloudinary.com/dnkmxpujh/image/upload/v1676023777/banner2_okkqac.png", null)); slideModels.add(new SlideModel("https://res.cloudinary.com/dnkmxpujh/image/upload/v1676023775/banner3_rklfi6.png", null)); @@ -34,7 +62,59 @@ public class HomeFragment extends Fragment { slideModels.add(new SlideModel("https://res.cloudinary.com/dnkmxpujh/image/upload/v1676023778/banner5_b4d1b8.png", null)); imageSlider.setImageList(slideModels, ScaleTypes.FIT); + // Inflate the layout for this fragment return view; } + + private List getListMenu() { + List listMenu = new ArrayList<>(); + + listMenu.add(new Menu("Recommend Food", listFood)); + listMenu.add(new Menu("Drinks", drinkFood)); + + return listMenu; + } + + private void getListFood() { + FoodApi.apiService.bestFoodResponse().enqueue(new Callback>() { + @Override + public void onResponse(Call> call, Response> response) { + List foodData = response.body(); + + for(Food tempFood: foodData){ + listFood.add(tempFood); + } + + drinkListFood(); + } + + @Override + public void onFailure(Call> call, Throwable t) { + Toast.makeText(getContext(), "Lỗi" + t, Toast.LENGTH_LONG).show(); + } + }); + } + + private void drinkListFood() { + FoodApi.apiService.drinksFoodResponse().enqueue(new Callback>() { + @Override + public void onResponse(Call> call, Response> response) { + List foodData = response.body(); + + for(Food tempFood: foodData){ + drinkFood.add(tempFood); + } + + + menuAdapter.setData(getListMenu()); + rcvMenu.setAdapter(menuAdapter); + } + + @Override + public void onFailure(Call> call, Throwable t) { + Toast.makeText(getContext(), "Lỗi" + t, Toast.LENGTH_LONG).show(); + } + }); + } } \ No newline at end of file diff --git a/app/src/main/java/com/capstone/foodify/DistrictWardResponse/Data.java b/app/src/main/java/com/capstone/foodify/Model/DistrictWard/Data.java similarity index 91% rename from app/src/main/java/com/capstone/foodify/DistrictWardResponse/Data.java rename to app/src/main/java/com/capstone/foodify/Model/DistrictWard/Data.java index 1d70605..79f5898 100644 --- a/app/src/main/java/com/capstone/foodify/DistrictWardResponse/Data.java +++ b/app/src/main/java/com/capstone/foodify/Model/DistrictWard/Data.java @@ -1,4 +1,4 @@ -package com.capstone.foodify.DistrictWardResponse; +package com.capstone.foodify.Model.DistrictWard; import java.util.List; diff --git a/app/src/main/java/com/capstone/foodify/DistrictWardResponse/Datas.java b/app/src/main/java/com/capstone/foodify/Model/DistrictWard/Datas.java similarity index 97% rename from app/src/main/java/com/capstone/foodify/DistrictWardResponse/Datas.java rename to app/src/main/java/com/capstone/foodify/Model/DistrictWard/Datas.java index a83dbbf..0b66fed 100644 --- a/app/src/main/java/com/capstone/foodify/DistrictWardResponse/Datas.java +++ b/app/src/main/java/com/capstone/foodify/Model/DistrictWard/Datas.java @@ -1,4 +1,4 @@ -package com.capstone.foodify.DistrictWardResponse; +package com.capstone.foodify.Model.DistrictWard; public class Datas { private String _id; diff --git a/app/src/main/java/com/capstone/foodify/DistrictWardResponse/DisctrictWardResponse.java b/app/src/main/java/com/capstone/foodify/Model/DistrictWard/DisctrictWardResponse.java similarity index 91% rename from app/src/main/java/com/capstone/foodify/DistrictWardResponse/DisctrictWardResponse.java rename to app/src/main/java/com/capstone/foodify/Model/DistrictWard/DisctrictWardResponse.java index f858cfc..6edad3c 100644 --- a/app/src/main/java/com/capstone/foodify/DistrictWardResponse/DisctrictWardResponse.java +++ b/app/src/main/java/com/capstone/foodify/Model/DistrictWard/DisctrictWardResponse.java @@ -1,4 +1,4 @@ -package com.capstone.foodify.DistrictWardResponse; +package com.capstone.foodify.Model.DistrictWard; public class DisctrictWardResponse { private int exitcode; 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 new file mode 100644 index 0000000..b938436 --- /dev/null +++ b/app/src/main/java/com/capstone/foodify/Model/Food/Food.java @@ -0,0 +1,80 @@ +package com.capstone.foodify.Model.Food; + +public class Food { + private String id; + private String img; + private String name; + private String dsc; + private String price; + private String rate; + private String country; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getImg() { + return img; + } + + public void setImg(String img) { + this.img = img; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDsc() { + return dsc; + } + + public void setDsc(String dsc) { + this.dsc = dsc; + } + + public String getPrice() { + return price; + } + + public void setPrice(String price) { + this.price = price; + } + + public String getRate() { + return rate; + } + + public void setRate(String rate) { + this.rate = rate; + } + + public String getCountry() { + return country; + } + + public void setCountry(String country) { + this.country = country; + } + + @Override + public String toString() { + return "Food{" + + "id='" + id + '\'' + + ", img='" + img + '\'' + + ", name='" + name + '\'' + + ", dsc='" + dsc + '\'' + + ", price='" + price + '\'' + + ", rate='" + rate + '\'' + + ", country='" + country + '\'' + + '}'; + } +} diff --git a/app/src/main/java/com/capstone/foodify/Model/Food/FoodAdapter.java b/app/src/main/java/com/capstone/foodify/Model/Food/FoodAdapter.java new file mode 100644 index 0000000..f629592 --- /dev/null +++ b/app/src/main/java/com/capstone/foodify/Model/Food/FoodAdapter.java @@ -0,0 +1,75 @@ +package com.capstone.foodify.Model.Food; + +import android.text.Layout; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.capstone.foodify.R; +import com.squareup.picasso.Picasso; + +import java.util.List; + +public class FoodAdapter extends RecyclerView.Adapter{ + + private List listFood; + + public void setData(List list) { + this.listFood = list; + notifyDataSetChanged(); + } + + @NonNull + @Override + public FoodViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_foods, parent, false); + return new FoodViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull FoodViewHolder holder, int position) { + Food food = listFood.get(position); + if(food == null){ + return; + } + + String foodName = food.getName(); + if(foodName.length() >= 19){ + StringBuilder stringBuilder = new StringBuilder(food.getName()); + stringBuilder.replace(19, food.getName().length(), "..." ); + holder.name.setText(stringBuilder); + } else { + holder.name.setText(foodName); + } + Picasso.get().load(food.getImg()).into(holder.image); + holder.price.setText(food.getPrice()); + } + + @Override + public int getItemCount() { + if(listFood != null) { + return listFood.size(); + } + return 0; + } + + public class FoodViewHolder extends RecyclerView.ViewHolder{ + + private ImageView image; + private TextView name, price; + + public FoodViewHolder(@NonNull View itemView) { + super(itemView); + + image = itemView.findViewById(R.id.image_view); + name = itemView.findViewById(R.id.title); + price = itemView.findViewById(R.id.price); + + } + } +} diff --git a/app/src/main/java/com/capstone/foodify/Model/Menu/Menu.java b/app/src/main/java/com/capstone/foodify/Model/Menu/Menu.java new file mode 100644 index 0000000..f7f3903 --- /dev/null +++ b/app/src/main/java/com/capstone/foodify/Model/Menu/Menu.java @@ -0,0 +1,32 @@ +package com.capstone.foodify.Model.Menu; + +import com.capstone.foodify.Model.Food.Food; + +import java.util.List; + +public class Menu { + + private String nameMenu; + private List foods; + + public Menu(String nameMenu, List foods) { + this.nameMenu = nameMenu; + this.foods = foods; + } + + public String getNameMenu() { + return nameMenu; + } + + public void setNameMenu(String nameMenu) { + this.nameMenu = nameMenu; + } + + public List getFoods() { + return foods; + } + + public void setFoods(List foods) { + this.foods = foods; + } +} diff --git a/app/src/main/java/com/capstone/foodify/Model/Menu/MenuAdapter.java b/app/src/main/java/com/capstone/foodify/Model/Menu/MenuAdapter.java new file mode 100644 index 0000000..3e0a4f0 --- /dev/null +++ b/app/src/main/java/com/capstone/foodify/Model/Menu/MenuAdapter.java @@ -0,0 +1,78 @@ +package com.capstone.foodify.Model.Menu; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.capstone.foodify.Model.Food.FoodAdapter; +import com.capstone.foodify.R; + +import java.util.List; + +public class MenuAdapter extends RecyclerView.Adapter{ + + private Context context; + private List listMenu; + + public MenuAdapter(Context context) { + this.context = context; + } + + public void setData(List list){ + this.listMenu = list; + notifyDataSetChanged(); + } + + @NonNull + @Override + public MenuViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.menu, parent, false); + return new MenuViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull MenuViewHolder holder, int position) { + Menu menu = listMenu.get(position); + + if(menu == null){ + return; + } + + holder.titleMenu.setText(menu.getNameMenu()); + + LinearLayoutManager linearLayoutManager = new LinearLayoutManager(context, RecyclerView.HORIZONTAL, false); + holder.rcvFood.setLayoutManager(linearLayoutManager); + + FoodAdapter foodAdapter = new FoodAdapter(); + foodAdapter.setData(menu.getFoods()); + + holder.rcvFood.setAdapter(foodAdapter); + } + + @Override + public int getItemCount() { + if(listMenu != null){ + return listMenu.size(); + } + return 0; + } + + public class MenuViewHolder extends RecyclerView.ViewHolder{ + + private TextView titleMenu; + private RecyclerView rcvFood; + + public MenuViewHolder(@NonNull View itemView) { + super(itemView); + + titleMenu = itemView.findViewById(R.id.menuTitle); + rcvFood = itemView.findViewById(R.id.recycler_view_food); + } + } +} diff --git a/app/src/main/res/layout/fragment_home.xml b/app/src/main/res/layout/fragment_home.xml index a8d9219..82fc115 100644 --- a/app/src/main/res/layout/fragment_home.xml +++ b/app/src/main/res/layout/fragment_home.xml @@ -71,32 +71,17 @@ app:layout_constraintEnd_toEndOf="parent" /> - - @@ -111,7 +96,7 @@ android:textSize="18sp" android:layout_width="wrap_content" android:layout_height="wrap_content" - app:layout_constraintTop_toBottomOf="@id/recycler_view_food" + app:layout_constraintTop_toBottomOf="@id/recycler_view_menu" app:layout_constraintStart_toStartOf="parent" /> @@ -131,35 +116,6 @@ app:layout_constraintEnd_toEndOf="parent" /> - - - - \ No newline at end of file diff --git a/app/src/main/res/layout/list_foods.xml b/app/src/main/res/layout/list_foods.xml index 4cb8dc9..a53aa23 100644 --- a/app/src/main/res/layout/list_foods.xml +++ b/app/src/main/res/layout/list_foods.xml @@ -2,7 +2,10 @@ + + + + + + + \ No newline at end of file