mirror of
https://github.com/Nezumi-2711/PRM392.git
synced 2026-09-22 13:48:29 +00:00
Search all food
This commit is contained in:
@@ -20,19 +20,24 @@
|
||||
android:theme="@style/Theme.Foodify"
|
||||
tools:replace="android:theme"
|
||||
tools:targetApi="31">
|
||||
<activity
|
||||
android:name=".SearchActivity"
|
||||
android:exported="false"
|
||||
android:theme="@style/Theme.Foodify.NoActionBar" />
|
||||
<activity
|
||||
android:name=".OrderDetail"
|
||||
android:exported="true"
|
||||
android:launchMode="singleTask">
|
||||
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
<data android:scheme="demozpdk"
|
||||
android:host="app" />
|
||||
</intent-filter>
|
||||
|
||||
<data
|
||||
android:host="app"
|
||||
android:scheme="demozpdk" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".ShowComment"
|
||||
|
||||
@@ -277,6 +277,7 @@ public class Home extends AppCompatActivity implements NavigationView.OnNavigati
|
||||
mSlider.setPresetIndicator(SliderLayout.PresetIndicators.Center_Bottom);
|
||||
mSlider.setCustomAnimation(new DescriptionAnimation());
|
||||
mSlider.setDuration(4000);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -483,4 +484,18 @@ public class Home extends AppCompatActivity implements NavigationView.OnNavigati
|
||||
dialog.show();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
// Inflate the menu; this adds items to the action bar if it is present.
|
||||
getMenuInflater().inflate(R.menu.home, menu);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
|
||||
if(item.getItemId() == R.id.menu_search)
|
||||
startActivity(new Intent(Home.this, SearchActivity.class));
|
||||
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,314 @@
|
||||
package com.waterbase.foodify;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.app.ActionBar;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.text.Editable;
|
||||
import android.text.SpannableStringBuilder;
|
||||
import android.text.Spanned;
|
||||
import android.text.TextWatcher;
|
||||
import android.text.style.StrikethroughSpan;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.firebase.ui.database.FirebaseRecyclerAdapter;
|
||||
import com.firebase.ui.database.FirebaseRecyclerOptions;
|
||||
import com.google.firebase.database.DataSnapshot;
|
||||
import com.google.firebase.database.DatabaseError;
|
||||
import com.google.firebase.database.DatabaseReference;
|
||||
import com.google.firebase.database.FirebaseDatabase;
|
||||
import com.google.firebase.database.Query;
|
||||
import com.google.firebase.database.ValueEventListener;
|
||||
import com.mancj.materialsearchbar.MaterialSearchBar;
|
||||
import com.squareup.picasso.Picasso;
|
||||
import com.waterbase.foodify.Common.Common;
|
||||
import com.waterbase.foodify.Database.Database;
|
||||
import com.waterbase.foodify.Interface.ItemClickListener;
|
||||
import com.waterbase.foodify.Model.Food;
|
||||
import com.waterbase.foodify.Model.Order;
|
||||
import com.waterbase.foodify.ViewHolder.FoodViewHolder;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class SearchActivity extends AppCompatActivity {
|
||||
|
||||
//Search
|
||||
FirebaseRecyclerAdapter<Food, FoodViewHolder> adapter;
|
||||
FirebaseRecyclerAdapter<Food, FoodViewHolder> searchAdapter;
|
||||
List<String> suggestList = new ArrayList<>();
|
||||
MaterialSearchBar materialSearchBar;
|
||||
|
||||
RecyclerView recyclerView;
|
||||
RecyclerView.LayoutManager layoutManager;
|
||||
|
||||
FirebaseDatabase database;
|
||||
DatabaseReference foodList;
|
||||
|
||||
//Favorites
|
||||
Database localDB;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_search);
|
||||
|
||||
//Firebase
|
||||
database = FirebaseDatabase.getInstance();
|
||||
foodList = database.getReference("Foods");
|
||||
|
||||
//Local DB
|
||||
localDB = new Database(this);
|
||||
|
||||
recyclerView = (RecyclerView) findViewById(R.id.recyler_search);
|
||||
recyclerView.setHasFixedSize(true);
|
||||
layoutManager = new LinearLayoutManager(this);
|
||||
recyclerView.setLayoutManager(layoutManager);
|
||||
|
||||
//Search
|
||||
materialSearchBar = (MaterialSearchBar) findViewById(R.id.searchBar);
|
||||
materialSearchBar.setHint("Enter your food");
|
||||
loadSuggest();
|
||||
materialSearchBar.setCardViewElevation(10);
|
||||
materialSearchBar.addTextChangeListener(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) {
|
||||
//When user type their text, we will change suggest list
|
||||
|
||||
List<String> suggest = new ArrayList<String>();
|
||||
for (String search : suggestList) {
|
||||
if (search.toLowerCase().contains(materialSearchBar.getText().toLowerCase()))
|
||||
suggest.add(search);
|
||||
}
|
||||
materialSearchBar.setLastSuggestions(suggest);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterTextChanged(Editable s) {
|
||||
|
||||
}
|
||||
});
|
||||
materialSearchBar.setOnSearchActionListener(new MaterialSearchBar.OnSearchActionListener() {
|
||||
@Override
|
||||
public void onSearchStateChanged(boolean enabled) {
|
||||
//When search bar is close
|
||||
//Restore original adapter
|
||||
if (!enabled)
|
||||
recyclerView.setAdapter(adapter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSearchConfirmed(CharSequence text) {
|
||||
//When search finish
|
||||
//Show result of search adapter
|
||||
startSearch(text);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onButtonClicked(int buttonCode) {
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
//Load add foods
|
||||
loadAddFood();
|
||||
}
|
||||
|
||||
private void loadAddFood() {
|
||||
//Create query by category Id
|
||||
Query searchByName = foodList;
|
||||
//Create Options with query
|
||||
FirebaseRecyclerOptions<Food> foodOptions = new FirebaseRecyclerOptions.Builder<Food>()
|
||||
.setQuery(searchByName, Food.class)
|
||||
.build();
|
||||
|
||||
adapter = new FirebaseRecyclerAdapter<Food, FoodViewHolder>(foodOptions) {
|
||||
@Override
|
||||
protected void onBindViewHolder(@NonNull FoodViewHolder viewHolder, int position, @NonNull Food model) {
|
||||
viewHolder.food_name.setText(model.getName());
|
||||
|
||||
if (Integer.parseInt(model.getDiscount()) > 0) {
|
||||
String foodPrice = model.getPrice() + "đ";
|
||||
long newFoodPrice = Long.parseLong(model.getPrice()) - Long.parseLong(model.getPrice()) * Long.parseLong(model.getDiscount()) / 100;
|
||||
SpannableStringBuilder spnBuilder = new SpannableStringBuilder(foodPrice);
|
||||
StrikethroughSpan strikethroughSpan = new StrikethroughSpan();
|
||||
spnBuilder.setSpan(strikethroughSpan, 0, foodPrice.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
viewHolder.food_price.setText(spnBuilder);
|
||||
viewHolder.newPrice.setText(newFoodPrice + "đ");
|
||||
} else {
|
||||
viewHolder.food_price.setText(String.format("%s đ", model.getPrice()));
|
||||
viewHolder.discount.setVisibility(View.GONE);
|
||||
viewHolder.newPrice.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
|
||||
viewHolder.discount.setText("- " + model.getDiscount() + "%");
|
||||
Picasso.with(getBaseContext()).load(model.getImage()).into(viewHolder.food_image);
|
||||
|
||||
//Quick Cart
|
||||
|
||||
viewHolder.quick_cart.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
boolean ifExists = new Database(getBaseContext()).checkFoodExists(adapter.getRef(viewHolder.getAdapterPosition()).getKey(), Common.currentUser.getPhone());
|
||||
if (!ifExists) {
|
||||
new Database(getBaseContext()).addToCart(new Order(
|
||||
Common.currentUser.getPhone(),
|
||||
adapter.getRef(viewHolder.getAdapterPosition()).getKey(),
|
||||
model.getName(),
|
||||
"1",
|
||||
model.getPrice(),
|
||||
model.getDiscount(),
|
||||
model.getImage()
|
||||
));
|
||||
} else {
|
||||
new Database(getBaseContext()).increaseCart(Common.currentUser.getPhone(), adapter.getRef(viewHolder.getAdapterPosition()).getKey());
|
||||
}
|
||||
|
||||
Toast.makeText(SearchActivity.this, "Đã thêm vào giỏ hàng!", Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
//Add Favorites
|
||||
if (localDB.isFavorite(adapter.getRef(position).getKey(), Common.currentUser.getPhone()))
|
||||
viewHolder.fav_image.setImageResource(R.drawable.ic_baseline_favorite_24);
|
||||
|
||||
//Click to change state of Favorites
|
||||
viewHolder.fav_image.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (!localDB.isFavorite(adapter.getRef(viewHolder.getAdapterPosition()).getKey(), Common.currentUser.getPhone())) {
|
||||
localDB.addToFavorites(adapter.getRef(viewHolder.getAdapterPosition()).getKey(), Common.currentUser.getPhone());
|
||||
viewHolder.fav_image.setImageResource(R.drawable.ic_baseline_favorite_24);
|
||||
Toast.makeText(SearchActivity.this, model.getName() + " đã thêm vào danh sách yêu thích", Toast.LENGTH_SHORT).show();
|
||||
} else {
|
||||
localDB.removeFromFavorites(adapter.getRef(viewHolder.getAdapterPosition()).getKey(), Common.currentUser.getPhone());
|
||||
viewHolder.fav_image.setImageResource(R.drawable.ic_baseline_favorite_border_24);
|
||||
Toast.makeText(SearchActivity.this, model.getName() + " đã xoá khỏi danh sách yêu thích", Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
viewHolder.setItemClickListener(new ItemClickListener() {
|
||||
@Override
|
||||
public void onClick(View view, int position, boolean isLongClick) {
|
||||
//Start Activity
|
||||
Intent foodDetail = new Intent(SearchActivity.this, FoodDetail.class);
|
||||
foodDetail.putExtra("FoodId", adapter.getRef(position).getKey()); // Send Food Id to new activity
|
||||
startActivity(foodDetail);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public FoodViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
View itemView = LayoutInflater.from(parent.getContext())
|
||||
.inflate(R.layout.food_item, parent, false);
|
||||
return new FoodViewHolder(itemView);
|
||||
}
|
||||
};
|
||||
|
||||
//Set Adapter
|
||||
recyclerView.setAdapter(adapter);
|
||||
adapter.startListening();
|
||||
|
||||
recyclerView.getAdapter().notifyDataSetChanged();
|
||||
recyclerView.scheduleLayoutAnimation();
|
||||
}
|
||||
|
||||
private void loadSuggest() {
|
||||
foodList.addListenerForSingleValueEvent(new ValueEventListener() {
|
||||
@Override
|
||||
public void onDataChange(DataSnapshot dataSnapshot) {
|
||||
for (DataSnapshot postSnapshot : dataSnapshot.getChildren()) {
|
||||
Food item = postSnapshot.getValue(Food.class);
|
||||
suggestList.add(item.getName());
|
||||
}
|
||||
|
||||
materialSearchBar.setLastSuggestions(suggestList);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCancelled(DatabaseError databaseError) {
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void startSearch(CharSequence text) {
|
||||
//Create query by name
|
||||
Query searchByName = foodList.orderByChild("name").equalTo(text.toString());
|
||||
//Create options with query
|
||||
FirebaseRecyclerOptions<Food> foodOptions = new FirebaseRecyclerOptions.Builder<Food>()
|
||||
.setQuery(searchByName, Food.class)
|
||||
.build();
|
||||
searchAdapter = new FirebaseRecyclerAdapter<Food, FoodViewHolder>(foodOptions) {
|
||||
@Override
|
||||
protected void onBindViewHolder(@NonNull FoodViewHolder viewHolder, int i, @NonNull Food model) {
|
||||
viewHolder.food_name.setText(model.getName());
|
||||
|
||||
if (Integer.parseInt(model.getDiscount()) > 0) {
|
||||
String foodPrice = model.getPrice() + "đ";
|
||||
long newFoodPrice = Long.parseLong(model.getPrice()) - Long.parseLong(model.getPrice()) * Long.parseLong(model.getDiscount()) / 100;
|
||||
SpannableStringBuilder spnBuilder = new SpannableStringBuilder(foodPrice);
|
||||
StrikethroughSpan strikethroughSpan = new StrikethroughSpan();
|
||||
spnBuilder.setSpan(strikethroughSpan, 0, foodPrice.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
viewHolder.food_price.setText(spnBuilder);
|
||||
viewHolder.newPrice.setText(newFoodPrice + "đ");
|
||||
} else {
|
||||
viewHolder.food_price.setText(String.format("%s đ", model.getPrice()));
|
||||
viewHolder.discount.setVisibility(View.GONE);
|
||||
viewHolder.newPrice.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
Picasso.with(getBaseContext()).load(model.getImage()).into(viewHolder.food_image);
|
||||
|
||||
viewHolder.setItemClickListener(new ItemClickListener() {
|
||||
@Override
|
||||
public void onClick(View view, int position, boolean isLongClick) {
|
||||
//Start Activity
|
||||
Intent foodDetail = new Intent(SearchActivity.this, FoodDetail.class);
|
||||
foodDetail.putExtra("FoodId", searchAdapter.getRef(position).getKey()); // Send Food Id to new activity
|
||||
startActivity(foodDetail);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public FoodViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
View itemView = LayoutInflater.from(parent.getContext())
|
||||
.inflate(R.layout.food_item, parent, false);
|
||||
return new FoodViewHolder(itemView);
|
||||
}
|
||||
};
|
||||
|
||||
searchAdapter.startListening();
|
||||
recyclerView.setAdapter(searchAdapter); //Set adapter for Recycler View is Search result
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStop() {
|
||||
if(adapter != null)
|
||||
adapter.stopListening();
|
||||
if(searchAdapter != null)
|
||||
searchAdapter.stopListening();
|
||||
super.onStop();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
<vector android:height="24dp" android:tint="#FFFFFF"
|
||||
android:viewportHeight="24" android:viewportWidth="24"
|
||||
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="@android:color/white" android:pathData="M15.5,14h-0.79l-0.28,-0.27C15.41,12.59 16,11.11 16,9.5 16,5.91 13.09,3 9.5,3S3,5.91 3,9.5 5.91,16 9.5,16c1.61,0 3.09,-0.59 4.23,-1.57l0.27,0.28v0.79l5,4.99L20.49,19l-4.99,-5zM9.5,14C7.01,14 5,11.99 5,9.5S7.01,5 9.5,5 14,7.01 14,9.5 11.99,14 9.5,14z"/>
|
||||
</vector>
|
||||
@@ -0,0 +1,33 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout 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/swipe_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
tools:context=".FoodList">
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<com.mancj.materialsearchbar.MaterialSearchBar
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentTop="true"
|
||||
android:id="@+id/searchBar"
|
||||
app:mt_speechMode="false"
|
||||
app:mt_hint="Enter your food"
|
||||
/>
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:layout_below="@+id/searchBar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:id="@+id/recyler_search"
|
||||
android:scrollbars="vertical"
|
||||
/>
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
|
||||
@@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
>
|
||||
|
||||
<item
|
||||
android:id="@+id/menu_search"
|
||||
android:icon="@drawable/ic_baseline_search_24"
|
||||
android:iconTint="@color/white"
|
||||
android:title=""
|
||||
app:showAsAction="always"
|
||||
/>
|
||||
|
||||
|
||||
</menu>
|
||||
Reference in New Issue
Block a user