The text i enter in searchView disappears on config change.
I am already handling the config change but still its not working.
As i have used fragments, so below code is written inside fragment.
Please solve my problem with respect to that.
My problem is i am not able to retrieve savedInstance in onActivityCreated method
Below is my code:
Snippets of useful code
private String searchQuery="";
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
if(savedInstanceState != null)
searchQuery = savedInstanceState.getString(Tag.SEARCH_QUERY);
}
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putString(Tag.SEARCH_QUERY, searchQuery);
}
#Override
public void onCreateOptionsMenu(Menu menu,MenuInflater menuInflater) {
// Inflate the menu; this adds items to the action bar if it is present.
menuInflater.inflate(R.menu.menu_search, menu);
MenuItem menuItem = menu.findItem(R.id.action_search);
SearchView searchView = null;
if (menuItem != null)
searchView = (SearchView) menuItem.getActionView();
if (searchView != null) {
searchView.setQuery(searchQuery,false);
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String query) {
//searching is done in async task
searchQuery = query;
NetworkUtility.onProgressBarShow(getActivity());
MyAsyncTaskDownloadDetails myAsyncTaskDownloadDetails = new MyAsyncTaskDownloadDetails();
myAsyncTaskDownloadDetails.execute(new String[]{Tag.PLP_URL + query, Tag.PLP,""});
return true;
}
#Override
public boolean onQueryTextChange(String newText) {
return true;
}
});
}
super.onCreateOptionsMenu(menu, menuInflater);
}
}
First of all you are saving queryText in onQueryTextSubmit callback which means searchQuerywill remain empty unless and until user have submitted query for search, so keep that in mind.
Secondly try following code. It will work I have tested it.
if(searchQuery.length()>0){
//See this commented code
// if(Utils.hasIceCreamSandwich()) {
// searchMenuItem.expandActionView();
// }else {
// MenuItemCompat.expandActionView(searchMenuItem);
// }
MenuItemCompat.expandActionView(menuItem);
searchView.setQuery(searchQuery, false);
}
Related
Currently, I'm working on an activity that has a RecyclerView and SearchView in it.Now the RecyclerView and SearchView are working fine but there is a problem that I don't know how to resolve, you see in the searchView part we were a task to make a SearchView that accepts 2 or more searchItems that must be separated by a comma or space in order to filter the recyclerview again if the second searchitem matches an item in the RecyclerView, for example I type in searchitem "Big" i'll need to separate it again with another searchitem like "Black"
here is the code for the SearchView
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.pet_book_main);
if(savedInstanceState != null){
mSearchString=savedInstanceState.getString(SEARCH_KEY);
}
pet_title=(TextView)findViewById(R.id.pet_book_title);
petbook=(RecyclerView)findViewById(R.id.pet_book_pet);
navbot=(BottomNavigationView) findViewById(R.id.petbook_navbot);
toolbar=(Toolbar)findViewById(R.id.petbook_toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setDisplayShowTitleEnabled(false);
toolbar.setTitle("");
linearLayoutManager=new LinearLayoutManager(this);
petbook.setHasFixedSize(true);
petbook.setLayoutManager(linearLayoutManager);
refresh();
disableShiftMode(navbot);
}
#Override
public boolean onCreateOptionsMenu(final Menu menu) {
MenuInflater menuInflater= getMenuInflater();
menuInflater.inflate(R.menu.petbook_searck,menu);
searchItem=menu.findItem(R.id.pet_book_search_mode);
searchView =(SearchView)MenuItemCompat.getActionView(searchItem);
if (mSearchString != null && !mSearchString.isEmpty()) {
searchItem.expandActionView();
searchView.setQuery(mSearchString, true);
searchView.clearFocus();
}
search(searchView);
MenuItemCompat.setOnActionExpandListener(searchItem, new MenuItemCompat.OnActionExpandListener() {
#Override
public boolean onMenuItemActionExpand(MenuItem item) {
pet_title.setVisibility(View.INVISIBLE);
return true;
}
#Override
public boolean onMenuItemActionCollapse(MenuItem item) {
pet_title.setVisibility(View.VISIBLE);
return true;
}
});
return true;
}
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
mSearchString = searchView.getQuery().toString();
outState.putString(SEARCH_KEY, mSearchString);
}
public void search(android.support.v7.widget.SearchView search)
{
search.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String query) {
return false;
}
#Override
public boolean onQueryTextChange(String newText) {
newText=newText.toLowerCase();
newList=new ArrayList<>();
for(petbook_getItem items : bookItem){
String pets=items.getPet_name().toLowerCase();
if(pets.contains(newText))
newList.add(items);
}
adapter.filterSearch(newList);
adapter.notifyDataSetChanged();
return true;
}
});
}
This code handles user input in search which can be multiple comma separated search items:
search.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
.....
#Override
public boolean onQueryTextChange(String newText) {
newText = newText.toLowerCase();
// remove leading comma or space
String string2 = newText.replaceAll("^[,\\s]+", "");
// return early for invalid input (empty)
if (string2.isEmpty()) {
return true;
}
// split by comma & space if any
List<String> inputList = Arrays.asList(string2.split("[,\\s]+"));
newList = new ArrayList<>();
for (petbook_getItem items : bookItem){
String pets = items.getPet_name().toLowerCase();
// Check for matching by looping through each search items
for (String inputTxt : inputList) {
if (pets.contains(inputTxt)) {
newList.add(items);
break;
}
}
}
adapter.filterSearch(newList);
adapter.notifyDataSetChanged();
return true;
}
});
I have SearchView which I want to programmatically expand and set text when the device orientation change. I tried many found solution but nothing work. If I use only setQuery then my list is filtered, but when I use also expandActionView then the search view does not contain the given search text and onQueryTextChange is called twice, first with the given text and the second time with the empty text.
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
menu.clear();
inflater.inflate(R.menu.activity, menu);
SearchManager searchManager = (SearchManager) getActivity().getSystemService(Context.SEARCH_SERVICE);
MenuItem searchMenuItem = menu.findItem(R.id.search);
SearchView searchView = (SearchView) MenuItemCompat.getActionView(searchMenuItem);
searchView.setIconifiedByDefault(true);
searchView.setSearchableInfo(searchManager.getSearchableInfo(getActivity().getComponentName()));
searchView.setOnQueryTextListener(this);
MenuItemCompat.setOnActionExpandListener(searchMenuItem, new MenuItemCompat.OnActionExpandListener() {
#Override
public boolean onMenuItemActionCollapse(MenuItem item) {
mCurrentQueryString = null;
if (mAdapter != null) {
mAdapter.clearFilter();
mStopSearching = true;
}
return true;
}
#Override
public boolean onMenuItemActionExpand(MenuItem item) {
if (mAdapter != null) {
mStopSearching = false;
}
return true;
}
});
mSearchView = searchView;
mSearchMenuItem = searchMenuItem;
mSearchView.post(new Runnable() {
#Override
public void run() {
MenuItemCompat.expandActionView(mSearchMenuItem);
mSearchView.setQuery(mCurrentQueryString, true);
}
});
super.onCreateOptionsMenu(menu, inflater);
}
I use the search view in the fragment which is used in the view pager. The fragment is retained. The problem is that onQueryTextChange function is called twice, by the second time with the empty text, but I am not sure why. This function is also called with the empty text when I first time open the search view when the fragment is initialized, but when close the serach view and open it again, this function is not called.
How can I fix it?
I've also faced that issue. The solution I've come up with was via posting with handler.
#Override public boolean onPrepareOptionsMenu(Menu menu) {
...
// SearchView doesn't retain it's state after orientation change
// have to handle it the bad way (╯°□°)╯︵ ┻━┻
boolean isQueryExists = !TextUtils.isEmpty(mSearchQuery);
if (isQueryExists) {
// Calling directly doesn't take effect
// Custom runnable class in order to refrain from context leakage
new Handler(Looper.getMainLooper()).post(new SearchMenuRunnable(mSearchView, mSearchQuery));
}
...
}
SearchMenuRunnable.java
public class SearchMenuRunnable implements Runnable {
private WeakReference<SearchView> mSearchViewWeakReference;
private String mSearchQuery;
public SearchMenuRunnable(SearchView searchView, String searchQuery) {
mSearchViewWeakReference = new WeakReference<>(searchView);
mSearchQuery = searchQuery;
}
#Override public void run() {
if (null != mSearchViewWeakReference.get()) {
SearchView searchView = mSearchViewWeakReference.get();
searchView.setIconified(false);
searchView.setQuery(mSearchQuery, true);
searchView.clearFocus();
}
}
This are source from one of projects in github. You can examine them here, it's pretty simple project.
I have an Activity with a ListView and clickeable items to show details of each of them in a separate Activity. My main activity has a SearchView to filter those items. I want to be able to click on an item (that open's a new activity) and when i press back button, my searchView remains same (with my filtered list).
I implemented my searchview like this:
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
// Inflate menu to add items to action bar if it is present.
inflater.inflate(R.menu.menu_main, menu);
final MenuItem searchItem = menu.findItem(R.id.action_search);
mSearchView = (SearchView) searchItem.getActionView();
mSearchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String query) {
Log.w("SEARCH", "SearchOnQueryTextSubmit: " + query);
mQuery = query;
if (!mSearchView.isIconified()) {
mSearchView.setIconified(true);
}
searchItem.collapseActionView();
return false;
}
#Override
public boolean onQueryTextChange(String s) {
Log.w("SEARCH", "SearchOnQueryTextChanged: " + s);
mQuery = s;
contactAdapter.getFilter().filter(s);
return false;
}
});
And i was trying to implement something into onResume or on the same onCreateOptionsMenu to check if mQuery had something.
if (!TextUtils.isEmpty(mQuery)) {
final String thisQuery = mQuery;
mSearchView.post(new Runnable() {
#Override
public void run() {
Log.d(TAG, "onResume: setting mQuery to searchView");
Log.d(TAG, "mQuery: "+thisQuery);
MenuItemCompat.expandActionView(searchItem);
mSearchView.setQuery(thisQuery, true);
}
});
}
Tried on both methods but with no success. On onCreateOptionsMenu, if i debugg it, SearchView is called with my query to be filtered, but right after that, another call comes with an empty search! I don't know where this comes from.
Any help? Thanks!
I am glad this could help:
What you need is How to maintain the previous state of an activity. Check the selected answer here -
When using search view, I have a requirement from customer that they want to retain the search content after reopen the search view. My Search view is on a list view and do a real timing filtering based on what user input into the search box. When closed the search box by either click the back button on the phone or click the soft back button on the top left on action bar, the search box closed, search view iconfied. But when reopen it next time, the search query used last time is also been cleared, which I do not want.
My question is that is there a way I can keep the search view content there. Just hiding the search box, but not clear the content?
My related code are as follow:
MenuItem search;
SearchView searchView;
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.menu_locationlist_fragment, menu);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
search = menu.findItem(R.id.action_search_location_list);
searchView = (SearchView) MenuItemCompat.getActionView(search);
SearchManager searchManager = (SearchManager) getActivity().getSystemService(Context.SEARCH_SERVICE);
searchView.setSearchableInfo(searchManager.getSearchableInfo(getActivity().getComponentName()));
searchView.setIconifiedByDefault(false);
searchView.setOnQueryTextListener(this);
searchView.setOnQueryTextFocusChangeListener(new View.OnFocusChangeListener() {
#Override
public void onFocusChange(View v, boolean hasFocus) {
//This will make sure, when user closed search view, the list will be restored.
if(!hasFocus) {
Log.i(Tags.LOCATIONLIST,"Search Close");
search.collapseActionView();
} else {
}
}
}
});
ImageView closeButton = (ImageView)searchView.findViewById(R.id.search_close_btn);
closeButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
EditText searchEditText = (EditText)searchView.findViewById(R.id.search_src_text);
searchEditText.setText("");
if (((LocationListAdapter)locationListView.getAdapter())!=null) {
((LocationListAdapter) locationListView.getAdapter()).getFilter().filter("");
}
}
});
}
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_search_location_list:
((BaseActivity) getActivity()).onSearchRequested();
return true;
case R.id.action_refresh_location_list:
refreshLocationList();
return true;
default:
return false;
}
}
#Override
public boolean onQueryTextSubmit(String s) {
return false;
}
#Override
public boolean onQueryTextChange(String s) {
if (((LocationListAdapter)locationListView.getAdapter())!=null) {
if (TextUtils.isEmpty(s)) {
locationListView.clearTextFilter();
} else {
((LocationListAdapter) locationListView.getAdapter()).getFilter().filter(s);
//locationListView.setFilterText(s.toString());
}
}
return true;
}
Use
SearchView searchView = (SearchView) menu.findItem(R.id.menu_search).getActionView();
searchView.setIconified(false);
Any query text is cleared when iconified. So setIconified to false. And i have used android.widget.SearchView
Save your String in a variable (e.g. myWantedString) and
override setOnClickListener that trigers everytime you open the SearchView and use setQuery. Your code should be:
searchView.setOnSearchClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
searchView.setQuery(myWantedString, false);
}
});
To save your string each time the SearchView closes implement setOnCloseListener and override onClose():
searchView.setOnCloseListener(new SearchView.OnCloseListener()
{
#Override
public boolean onClose()
{
myWantedString = searchView.getQuery();
return false;
}
});
searchView.setQuery() works if was called with a delay after menu item expansion.
MenuItemCompat.setOnActionExpandListener(searchItem, new MenuItemCompat.OnActionExpandListener() {
#Override
public boolean onMenuItemActionExpand(MenuItem item) {
final SearchView searchView = (SearchView) MenuItemCompat.getActionView(item);
// set query text with a delay
searchView.post(new Runnable() {
#Override
public void run() {
searchView.setQuery(query, false);
}
});
return true;
}
#Override
public boolean onMenuItemActionCollapse(MenuItem item) {
return true;
}
});
You can create an Activity which can be called when the user searches and the search result can be stored in the Bundle during the callback method onPause or onSaveInstanceState , when the Activity is called once again restore it from the bundle.
MenuItem searchItem = menu.findItem(R.id.action_search);
SearchView searchView = (SearchView) searchItem.getActionView();
searchView.setIconified(false);
searchView.setOnSearchClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
searchView.setQuery("SEARCH_WORD", false);
}
});
https://developer.android.com/reference/android/widget/SearchView
Sets a listener to inform when the search button is pressed. This is only relevant when the text field is not visible by default. Calling setIconified(false) can also cause this listener to be informed.
I am using searchview in my application ( without action bar). How can I collapse searchview after query text submit?
I have these listeners ;
#Override
public boolean onQueryTextSubmit(String query) {
InputMethodManager imm = (InputMethodManager)thisFr.getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(globalSearch.getWindowToken(), 0);
return false;
}
#Override
public boolean onQueryTextChange(String newText) {
// TODO Auto-generated method stub
return false;
}
I don't use ActionBar so I don't have a function like collapseActionView().
you need to call setIconified(true) twice to actually collapse your search view, with first call text is cleared with second call keyboard and search view get closed.
You can do it this way in your activity, tested with actionbarsherlock (it even hides the keyboard, make sure to return false in onQueryTextSubmit):
private MenuItem searchMenuItem;
public MenuItem getSearchMenuItem() {
return searchMenuItem;
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// ...
searchMenuItem = menu.findItem(R.id.menu_search);
// ...
searchView.setOnQueryTextListener(new OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String query) {
MenuItem searchMenuItem = getSearchMenuItem();
if (searchMenuItem != null) {
searchMenuItem.collapseActionView();
}
return false;
}
#Override
public boolean onQueryTextChange(String newText) {
// ...
return true;
}
});
// ...
return super.onCreateOptionsMenu(menu);
}
If you are using the SearchView in the OptionsMenu, you ca call invalidateOptionsMenu()
//close suggestion list on query text submit
searchView.setIconified(true);
final MenuItem searchterm = menu.findItem(R.id.search);
SearchView searchView = null;
searchView = (SearchView) searchterm.getActionView();
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String query) {
searchterm.collapseActionView();
}});