/* * Copyright (C) 2013 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.eugene.fithealthmaingit.UI; import android.app.Activity; import android.content.ActivityNotFoundException; import android.content.Context; import android.content.Intent; import android.os.AsyncTask; import android.os.Build; import android.os.Bundle; import android.speech.RecognizerIntent; import android.support.annotation.Nullable; import android.support.v4.app.Fragment; import android.support.v4.widget.SwipeRefreshLayout; import android.support.v7.widget.Toolbar; import android.text.Editable; import android.text.InputType; import android.text.TextWatcher; import android.view.KeyEvent; import android.view.LayoutInflater; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.view.Window; import android.view.inputmethod.EditorInfo; import android.view.inputmethod.InputMethodManager; import android.widget.AbsListView; import android.widget.AdapterView; import android.widget.EditText; import android.widget.LinearLayout; import android.widget.ListView; import android.widget.TextView; import android.widget.Toast; import com.eugene.fithealthmaingit.Databases_Adapters_ListViews.FatSecretSearchList.SearchAdapterItemResult; import com.eugene.fithealthmaingit.Databases_Adapters_ListViews.FatSecretSearchList.SearchItemResult; import com.eugene.fithealthmaingit.Databases_Adapters_ListViews.LogQuickSearchData.LogQuickSearch; import com.eugene.fithealthmaingit.Databases_Adapters_ListViews.LogQuickSearchData.LogQuickSearchAdapter; import com.eugene.fithealthmaingit.FatSecretSearchAndGet.FatSecretSearchMethod; import com.eugene.fithealthmaingit.R; import com.eugene.fithealthmaingit.Utilities.Equations; import com.eugene.fithealthmaingit.Utilities.Globals; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import java.util.ArrayList; import java.util.Date; import java.util.HashSet; import java.util.Locale; import java.util.Set; /** * Search FatSecret Rest Api * Add items to LogQuickSearch */ public class ChooseAddMealSearchFragment extends Fragment implements AbsListView.OnScrollListener { private String mealType; private ListView mListViewSearchResults; private Toolbar mToolbarSearch; private EditText mEtSearch; private SearchAdapterItemResult mEtSearchAdapter; private ArrayList<SearchItemResult> mItem; private Set<String> set; private FatSecretSearchMethod mFatSecretSearch; private LogQuickSearchAdapter mRecentLogAdapter; private SwipeRefreshLayout mSwipeRefreshLayout; private int preLast; private String brand; private ListView listSearch; LinearLayout llSearch; private LogQuickSearchAdapter logQuickSearchAdapter; private View searchLine; @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { View v = inflater.inflate(R.layout.fragment_search_add_item_fatsecret, container, false); // Change the notification bar color if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { Window w = getActivity().getWindow(); w.setStatusBarColor(getResources().getColor(R.color.light_grey)); } // Get MealType (snack, breakfast, lunch, dinner) Bundle extras = getActivity().getIntent().getExtras(); if (extras != null) { mealType = extras.getString(Globals.MEAL_TYPE); } // Initialize FatSecretSearchMethod mFatSecretSearch = new FatSecretSearchMethod(); mSwipeRefreshLayout = (SwipeRefreshLayout) v.findViewById(R.id.swiperefresh); mSwipeRefreshLayout.setColorSchemeResources(R.color.primary, R.color.red, R.color.primary_dark); mSwipeRefreshLayout.setProgressViewOffset(true, Equations.dpToPx(getActivity(), 0), Equations.dpToPx(getActivity(), 112)); mSwipeRefreshLayout.setEnabled(false); mEtSearch = (EditText) v.findViewById(R.id.etSearch); // LogQuickSearch adapter to add items that have not been saved already mRecentLogAdapter = new LogQuickSearchAdapter(getActivity(), 0, LogQuickSearch.all()); // List for adding items to the mItem = new ArrayList<>(); // Set to prevent duplicates being saved in LogQuickSearch set = new HashSet<>(); /** * set mListViewSearchResults adapter to SearchAdapterItemResult */ llSearch = (LinearLayout) v.findViewById(R.id.llSearch); listSearch = (ListView) v.findViewById(R.id.listSearch); searchLine = v.findViewById(R.id.searchLine); logQuickSearchAdapter = new LogQuickSearchAdapter(getActivity(), 0, LogQuickSearch.all()); mEtSearchAdapter = new SearchAdapterItemResult(getActivity(), mItem); mListViewSearchResults = (ListView) v.findViewById(R.id.listView); ViewGroup header = (ViewGroup) inflater.inflate(R.layout.list_search_header, mListViewSearchResults, false); mListViewSearchResults.addHeaderView(header, null, false); mListViewSearchResults.setAdapter(mEtSearchAdapter); mListViewSearchResults.setOnScrollListener(this); mListViewSearchResults.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { Intent i = new Intent(getActivity(), SaveSearchAddItemActivityMain.class); i.putExtra(Globals.MEAL_TYPE, mealType); i.putExtra(Globals.MEAL_ID, mItem.get(position - 1).getID()); i.putExtra(Globals.MEAL_BRAND, mItem.get(position - 1).getBrand()); i.putExtra(Globals.MEAL_FAVORITE, "false"); startActivity(i); } }); // Toolbar mToolbarSearch = (Toolbar) v.findViewById(R.id.toolbar_search); mToolbarSearch.inflateMenu(R.menu.menu_search); mToolbarSearch.setNavigationIcon(R.mipmap.ic_arrow_back_grey); mToolbarSearch.setNavigationOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { getActivity().getSupportFragmentManager().popBackStack(); } }); mToolbarSearch.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() { @Override public boolean onMenuItemClick(MenuItem menuItem) { if (menuItem.getItemId() == R.id.action_clear) { mEtSearch.setText(""); } if (menuItem.getItemId() == R.id.action_voice) { promptSpeechInput(); } return false; } }); mEtSearch.addTextChangedListener(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) { if (mEtSearch.getText().toString().length() >= 1) { mToolbarSearch.getMenu().clear(); mToolbarSearch.inflateMenu(R.menu.menu_search_clear); logQuickSearchAdapter = new LogQuickSearchAdapter(getActivity(), 0, LogQuickSearch.FilterByName(mEtSearch.getText().toString())); listSearch.setAdapter(logQuickSearchAdapter); } else { mToolbarSearch.getMenu().clear(); mToolbarSearch.inflateMenu(R.menu.menu_search); logQuickSearchAdapter = new LogQuickSearchAdapter(getActivity(), 0, LogQuickSearch.all()); listSearch.setAdapter(logQuickSearchAdapter); } mItem.clear(); updateListView(); } @Override public void afterTextChanged(Editable s) { } }); // Quick Search Clicked, start search based on list Item clicked from last fragment Bundle extrasFromRecentCliced = this.getArguments(); if (extrasFromRecentCliced != null) { String mealName = extrasFromRecentCliced.getString("MealName"); if (mealName != null) { mEtSearch.setText(mealName); mToolbarSearch.getMenu().clear(); mToolbarSearch.inflateMenu(R.menu.menu_search_clear); searchFood(mealName, 0); } } else { mEtSearch.requestFocus(); ((InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE)).toggleSoftInput(InputMethodManager.SHOW_FORCED, InputMethodManager.HIDE_IMPLICIT_ONLY); } /** * Handles softKeyboard search icon being clicked */ mEtSearch.setOnEditorActionListener(new TextView.OnEditorActionListener() { @Override public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { if (actionId == EditorInfo.IME_ACTION_SEARCH) { ((InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE)).hideSoftInputFromWindow(mEtSearch.getWindowToken(), 0); listSearch.setVisibility(View.GONE); searchLine.setVisibility(View.GONE); searchFood(mEtSearch.getText().toString(), 0); mItem.clear(); mEtSearchAdapter.notifyDataSetChanged(); mEtSearch.clearFocus(); return true; } return false; } }); listSearch.setAdapter(logQuickSearchAdapter); listSearch.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { LogQuickSearch logQuickSearch = logQuickSearchAdapter.getItem(position); mEtSearch.setText(logQuickSearch.getName()); ((InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE)).hideSoftInputFromWindow(mEtSearch.getWindowToken(), 0); listSearch.setVisibility(View.GONE); searchLine.setVisibility(View.GONE); searchFood(logQuickSearch.getName(), 0); mItem.clear(); mEtSearchAdapter.notifyDataSetChanged(); mEtSearch.clearFocus(); } }); updateListView(); return v; } /** * Adds more items to the list if it is scrolled to the bottom */ private void addMoreListItems() { if (mItem.size() == 20) // needs to be refactored searchFood(mEtSearch.getText().toString(), 1); else if (mItem.size() == 40) searchFood(mEtSearch.getText().toString(), 2); else if (mItem.size() == 60) searchFood(mEtSearch.getText().toString(), 3); else if (mItem.size() == 80) searchFood(mEtSearch.getText().toString(), 4); else if (mItem.size() == 100) searchFood(mEtSearch.getText().toString(), 5); else if (mItem.size() == 120) searchFood(mEtSearch.getText().toString(), 6); else if (mItem.size() == 140) searchFood(mEtSearch.getText().toString(), 7); else if (mItem.size() == 160) searchFood(mEtSearch.getText().toString(), 8); else if (mItem.size() == 180) searchFood(mEtSearch.getText().toString(), 9); else if (mItem.size() == 200) searchFood(mEtSearch.getText().toString(), 10); } /** * Update the ListView based on mItem size */ private void updateListView() { if (mItem.size() == 0) { listSearch.setVisibility(View.VISIBLE); searchLine.setVisibility(View.VISIBLE); mListViewSearchResults.setVisibility(View.GONE); } else { mListViewSearchResults.setVisibility(View.VISIBLE); listSearch.setVisibility(View.GONE); searchLine.setVisibility(View.GONE); } mEtSearchAdapter.notifyDataSetChanged(); } /** * FatSecret Search method. * Connect to Rest and return search results based on text and page number * Implements FatSecretSearchMethod.class * * @param item string to search item * @param page_num currently showing 20 items per page. Adds more items if page num increases */ private void searchFood(final String item, final int page_num) { /** * Add Items to the recent database if item is added to the hash set */ for (int i = 0; i < mRecentLogAdapter.getCount(); i++) { LogQuickSearch ls = mRecentLogAdapter.getItem(i); String name = ls.getName(); set.add(name.toUpperCase()); } if (set.add(item.toUpperCase())) { LogQuickSearch recentLog = new LogQuickSearch(); recentLog.setName(item); recentLog.setDate(new Date()); recentLog.save(); mRecentLogAdapter.add(recentLog); mRecentLogAdapter.notifyDataSetChanged(); } AsyncTask<String, String, String> mAsyncTask = new AsyncTask<String, String, String>() { @Override protected void onPreExecute() { mSwipeRefreshLayout.setEnabled(true); mSwipeRefreshLayout.setRefreshing(true); } @Override protected String doInBackground(String... arg0) { JSONObject food = mFatSecretSearch.searchFood(item, page_num); JSONArray FOODS_ARRAY; try { if (food != null) { FOODS_ARRAY = food.getJSONArray("food"); if (FOODS_ARRAY != null) { for (int i = 0; i < FOODS_ARRAY.length(); i++) { JSONObject food_items = FOODS_ARRAY.optJSONObject(i); String food_name = food_items.getString("food_name"); String food_description = food_items.getString("food_description"); String[] row = food_description.split("-"); String id = food_items.getString("food_type"); if (id.equals("Brand")) { brand = food_items.getString("brand_name"); } if (id.equals("Generic")) { brand = "Generic"; } String food_id = food_items.getString("food_id"); mItem.add(new SearchItemResult(food_name, row[1].substring(1), "" + brand, food_id)); } } } } catch (JSONException exception) { exception.printStackTrace(); return "Error"; } return ""; } @Override protected void onCancelled() { } @Override protected void onPostExecute(String result) { super.onPostExecute(result); if (result.equals("Error")) Toast.makeText(getActivity(), "No Items Containing Your Search", Toast.LENGTH_SHORT).show(); mSwipeRefreshLayout.setRefreshing(false); mSwipeRefreshLayout.setEnabled(false); updateListView(); } }; mAsyncTask.execute(); } /** * Speech Input * Voice search then implements search method based on result */ public static int REQ_CODE_SPEECH_INPUT = 100; private void promptSpeechInput() { ((InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE)).hideSoftInputFromWindow(mEtSearch.getWindowToken(), 0); Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH); intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_FREE_FORM); intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE, Locale.getDefault()); intent.putExtra(RecognizerIntent.EXTRA_PROMPT, "Say Something"); try { startActivityForResult(intent, REQ_CODE_SPEECH_INPUT); } catch (ActivityNotFoundException a) { Toast.makeText(getActivity().getApplicationContext(), "Not Supported", Toast.LENGTH_SHORT).show(); } } /** * Set the text based on google voice then implement search */ @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == REQ_CODE_SPEECH_INPUT) { if (resultCode == Activity.RESULT_OK && null != data) { ArrayList<String> result = data.getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS); mEtSearch.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_CAP_SENTENCES); mEtSearch.setText(result.get(0)); searchFood(mEtSearch.getText().toString(), 0); mItem.clear(); mEtSearchAdapter.notifyDataSetChanged(); mEtSearch.clearFocus(); } } } /** * Calls addMoreListItems() if the last list position is visible */ @Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { switch (view.getId()) { case R.id.listView: final int lastItem = firstVisibleItem + visibleItemCount; if (lastItem == totalItemCount) { if (preLast != lastItem) { addMoreListItems(); preLast = lastItem; } } } } @Override public void onScrollStateChanged(AbsListView view, int scrollState) { } }