Search all food

This commit is contained in:
phanhuuloi27
2022-07-03 21:03:43 +07:00
parent 1568a1b5fc
commit da920372ab
6 changed files with 391 additions and 4 deletions
+9 -4
View File
@@ -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>
+15
View File
@@ -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>