I have an ActionBar with search field on top. In search field I have the "clear" icon, if you press on it clearFilterText() will be called.
I created search field like this:
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuUtil.addCommonMenuItems(this, menu);
getSupportMenuInflater().inflate(R.menu.guide_list_menu, menu);
MenuItem searchItem = menu.findItem(R.id.search_menu_item);
searchItem.setActionView(createSearchView());
searchItem.expandActionView();
searchItem.setVisible(true);
return true;
}
private View createSearchView() {
LayoutInflater inflater = LayoutInflater.from(getSupportActionBar().getThemedContext());
searchText = (EditText) inflater.inflate(R.layout.search_view, null);
searchText.setOnTouchListener(
new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
// ...
clearFilterText();
// ...
});
// ...
return searchText;
}
The problem is that TouchListener overwritten by ActionBar. Exactly place where it's overwritten is com.android.internal.view.menu.ActionMenuPresenter getItemView()
Are there any solution to make this TouchListener work?
Related
I am trying to access EditText field of SearchView (v7) inside my application but I am always ending up at null pointer exception.
So far I've tried a solution and tried to access the EditView using android:id/search_plate , R.id.search_plate, R.id.search_src_text and android:id/search_src_text but all in vain.
Code:
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.frag_menu_items, menu);
MenuItem menuItem = menu.findItem(R.id.action_search);
searchView = (SearchView) MenuItemCompat.getActionView(menuItem);
searchPlateId = searchView.getContext().getResources().getIdentifier("android:id/search_src_text", null, null);
searchPlate = (EditText) searchView.findViewById(searchPlateId);
searchPlate.setImeOptions(EditorInfo.IME_ACTION_SEARCH);
searchPlate.setOnEditorActionListener(new TextView.OnEditorActionListener() {
#Override
public boolean onEditorAction(TextView textView, int actionId, KeyEvent keyEvent) {
if (actionId == EditorInfo.IME_ACTION_SEARCH) {
ToastClass.getInstance().showCustomMsg(getActivity(),searchPlate.getText().toString());
}
return false;
}
});
//searchView.setOnQueryTextListener(this);
MenuItemCompat.setOnActionExpandListener(menuItem, new MenuItemCompat.OnActionExpandListener() {
#Override
public boolean onMenuItemActionCollapse(MenuItem item) {
// Do something when collapsed
// Toast.makeText(getActivity(),"collapsed",Toast.LENGTH_LONG).show();
searchMeta.setVisibility(View.GONE);
return true; // Return true to collapse action view
}
#Override
public boolean onMenuItemActionExpand(MenuItem item) {
// Do something when expanded
// Toast.makeText(getActivity(),"expanded",Toast.LENGTH_LONG).show();
searchMeta.setVisibility(View.VISIBLE);
return true; // Return true to expand action view
}
});
super.onCreateOptionsMenu(menu,inflater);
}
I am trying to access EditText field of SearchView (v7) inside my application.
You can do it with Java code.
For android.support.v7.widget.SearchView:
EditText editText = (EditText) searchView.findViewById(android.support.v7.appcompat.R.id.search_src_text);
For android.widget.SearchView:
EditText editText = (EditText) searchView.findViewById(android.R.id.search_src_text);
Try this
searchView = (SearchView) menu.findItem(R.id.search_plate).getActionView();
I have been working on an application where I have 6 tabs each of them having a listview in it. I want to filter the listview in each fragment depending upon the text in SearchView which is part of MainActivity. I have a working code for filtering records written in Listview adapter.
The issue is, whenever I want to search something using searchview, the current fragment listview gets filtered but as soon as I move from one fragment to other, the searchview gets reset and the text written in gets clear. That's why I don't get anything in other fragment to search for.
I have following code logic used
In MainActivity :
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu_order, menu);
if(searchView == null)
searchView = (SearchView) MenuItemCompat.getActionView(menu.findItem(R.id.action_search));
SearchManager searchManager = (SearchManager) getSystemService(SEARCH_SERVICE);
searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
return super.onCreateOptionsMenu(menu);
}
#Override
public boolean onPrepareOptionsMenu(Menu menu) {
return false;
}
In each of the fragment I have :
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_items, container, false);
setHasOptionsMenu(true);
return view;
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
// TODO Auto-generated method stub
super.onCreateOptionsMenu(menu, inflater);
}
#Override
public void onPrepareOptionsMenu(Menu menu) {
// TODO Auto-generated method stub
super.onPrepareOptionsMenu(menu);
android.view.MenuItem item = menu.findItem(R.id.action_search);
SearchView sv = new SearchView(((OrderActivity) getActivity()).getSupportActionBar().getThemedContext());
MenuItemCompat.setShowAsAction(item, MenuItemCompat.SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW | MenuItemCompat.SHOW_AS_ACTION_IF_ROOM);
MenuItemCompat.setActionView(item, sv);
sv.setOnQueryTextListener(this);
sv.setIconifiedByDefault(false);
}
#Override
public boolean onQueryTextSubmit(String query) {
return true;
}
#Override
public boolean onQueryTextChange(String newText) {
if (listAdapter != null) {
listAdapter.filter(newText);
}
return true;
}
Please suggest for solution on above issue.
Thanks in advance.
I have search view in my fragment. when I click on it , keyboard is open and I can type text. I want when I click on search button in keyboard , my query send to my server and get result but I don't know how get search event. any solution?
You have to extend OnQueryTextListener, attach the listener and implement onQueryTextSubmit.
Example:
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
searchView = (SearchView) menu.findItem(R.id.mActionSearch).getActionView();
searchView.setOnQueryTextListener(this);
return true;
}
#Override
public boolean onQueryTextSubmit(String query) {
//Do something here
return false;
}
#Override
public boolean onQueryTextChange(String newText) {
return false;
}
Pozzo Apps Answer is right
but for api below 11 and compat library you can use something like this :
MenuItem search_menu=(MenuItem)menu.findItem(R.id.action_search);
SearchView searchView =(SearchView)MenuItemCompat.getActionView(search_menu);
You can also apply setOnKeyListener on search view like as below:
searchview.setOnKeyListener(new View.OnKeyListener(
{
Public boolean onKey(View v, int keyCode, KeyEvent event)
{
if(event.getAction() == KeyEvent.ACTION_DOWN)
{
switch(keyCode)
{
Case KeyEvent.KECODE_ENTER:
// Apply action which you want on search key press on keypad
return true;
default:
break;
}
} return false;
}
});
You have to add new OnQueryTextListener, and implement onQueryTextSubmit. This also works in a fragment.
Example:
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.main_search, menu);
SearchView sv = (SearchView) menu.findItem(R.id.action_search).getActionView();
sv.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String query) {
//Do something here
Toast.makeText(getActivity(), "Search: " + query, Toast.LENGTH_SHORT ).show();
return false;
}
#Override
public boolean onQueryTextChange(String newText) {
return false;
}
});
super.onCreateOptionsMenu(menu,inflater);
}
I am currently using an ActionBar menu item to display a SearchView in the action bar. When the search menu item is expanded the soft keyboard is displayed which is what I want. Now, when the user presses the back button to close the soft keyboard, I would also like to collapse the SearchView in the action bar.
I have tried implementing the following listeners OnKeyListener and OnFocusChangeListener on the MenuItem and the ActionView. I have also tried using OnBackPressed() in the Activity. None of the above detect when the back button is used to close the soft keyboard.
Any ideas?
I have implemented OnActionExpandListener to know when the SearchView is visible.
I'll expand on #user1258568 's answer for the lazy. This worked for me. Note that it clears your query when focus is lost.
final MenuItem searchMenuItem = optionsMenu.findItem(R.id.search);
final SearchView searchView = (SearchView) searchMenuItem.getActionView();
searchView.setOnQueryTextFocusChangeListener(new View.OnFocusChangeListener() {
#Override
public void onFocusChange(View view, boolean queryTextFocused) {
if(!queryTextFocused) {
searchMenuItem.collapseActionView();
searchView.setQuery("", false);
}
}
});
I found a better solution.
searchView.setOnQueryTextFocusChangeListener().
The OnQueryTextFocusChangeListener gets called when the keyboard is displayed or hidden. Gets called first when the keyboard is displayed and the search view will have focus. Gets called again when keyboard is hidden and search view will lose focus, can close search viewthen using
menuItem.collapseActionView().
Just Override onBackPressed like this:
#Override
public void onBackPressed() {
if (searchView.isShown()){
searchView.onActionViewCollapsed(); //collapse your ActionView
searchView.setQuery("",false); //clears your query without submit
isClosed = true; //needed to handle closed by back
} else{
super.onBackPressed();
}
}
and your onCreateOptionsMenu would inflate the mSearchView like this:
#Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
getMenuInflater().inflate(R.menu.menu_search, menu);
mSearchView = (SearchView) menu.findItem(R.id.menu_action_search).getActionView();
mSearchView.setOnQueryTextListener(this);
mSearchView.setOnSearchClickListener(this);
mSearchView.setOnCloseListener(this);
isClosed = true;
return true;
}
have you class implement the following like this:
public class myActivity extends FragmentActivity implements
SearchView.OnQueryTextListener, View.OnClickListener, SearchView.OnCloseListener {
which you will also need:
#Override
public void onClick(View view) {
isClosed = false;
}
#Override
public boolean onClose() {
isClosed = true;
return false;
}
You will need to make "mSearchView" and "isClosed" both global variables to the activity.
The answer from Jon Willis works great. This is an improvement to his answer.
First, create a new class that implements View.OnFocusChangeListener:
public class SearchViewFocusListener implements View.OnFocusChangeListener {
private final MenuItem mMenuItem;
public SearchViewFocusListener(MenuItem menuItem) {
mMenuItem = menuItem;
}
#Override
public void onFocusChange(View v, boolean hasFocus) {
if (!hasFocus) {
mMenuItem.collapseActionView();
if (v instanceof SearchView) {
((SearchView) v).setQuery("", false);
}
}
}
}
Next, set the listener on your SearchView:
searchView.setOnQueryTextFocusChangeListener(new SearchViewFocusListener(menuItem));
You only need to put the "collapseActionView" attribute in the menu layout
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="#+id/menu_item_search"
android:title="#string/search"
android:iconifiedByDefault="true"
android:icon="#drawable/ic_action_search"
app:actionViewClass="android.support.v7.widget.SearchView"
app:showAsAction="ifRoom|collapseActionView"/> <--this one
</menu>
That will give you the functionality you look for all by itself.Don't forget to call the method "clearFocus" on the SearchView to close the keyboard once you send the query.
This is what I did for making the keyboard disappear. You can try to see if this works for you. I set the searchView to invisible and then to visible again.
//set query change listener
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener(){
#Override
public boolean onQueryTextChange(String newText) {
// TODO Auto-generated method stub
return false;
}
#Override
public boolean onQueryTextSubmit(String query) {
/**
* hides and then unhides search tab to make sure keyboard disappears when query is submitted
*/
searchView.setVisibility(View.INVISIBLE);
searchView.setVisibility(View.VISIBLE);
return false;
}
});
It's achievable like this:
private void setupSearchView(Menu menu) {
final MenuItem searchMenuItem = menu.findItem(R.id.action_search);
final SearchView searchView = (SearchView) searchMenuItem.getActionView();
[...]
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String query) {
searchMenuItem.collapseActionView();
return false;
}
#Override
public boolean onQueryTextChange(String newText) {
return true;
}
});
}
Solutions based on setOnQueryTextFocusChangeListener() did not work for me because the event was not launched - the searchView did not lose focus when submitted, probably because I perform the search in the same activity that contains the Search View.
Anyway, I think using OnQueryTextListener is more correct, as it describes the event of submitting text more precisely.
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getSupportMenuInflater().inflate(R.menu.home_screen, menu);
SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
final MenuItem searchMenuItem = menu.findItem(R.id.menu_search);
final SearchView searchView = (SearchView) searchMenuItem
.getActionView();
searchView.setIconifiedByDefault(false);
if (searchManager != null && searchView != null) {
searchView.setSearchableInfo(searchManager
.getSearchableInfo(getComponentName()));
searchView
.setOnQueryTextFocusChangeListener(new View.OnFocusChangeListener() {
#Override
public void onFocusChange(View v, boolean hasFocus) {
if (!hasFocus) {
if (searchMenuItem != null) {
searchMenuItem.collapseActionView();
}// end if
if (searchView != null) {
searchView.setQuery("", false);
}// end if
}// end if
}
});
searchView
.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String query) {
/**
* hides and then unhides search tab to make sure
* keyboard disappears when query is submitted
*/
if (searchView != null) {
searchView.setVisibility(View.INVISIBLE);
searchView.setVisibility(View.VISIBLE);
}
return false;
}
#Override
public boolean onQueryTextChange(String newText) {
// TODO Auto-generated method stub
return false;
}
});
}
return super.onCreateOptionsMenu(menu);
}
If you want to collapse keyboard when user clicks search icon on keyboard
this can be achieved by simple
inside onquerytextsubmitted {
searchView.clearfocus()
}
You need to call setIconified twice.
To actually collapse your search view and close the keyboard.
With first call text of search view is cleared with second call keyboard and search view get closed.
For some reason, menuItem.collapseActionView() did not work so I used searchView.setIconified(true) instead.
This gives the below result as the code sample.
final MenuItem searchItem = (MenuItem) menu.findItem(R.id.menu_item_search);
final SearchView searchView = (SearchView) searchItem.getActionView();
searchView.setOnQueryTextFocusChangeListener(new SearchView.OnFocusChangeListener() {
#Override
public void onFocusChange(View v, boolean hasFocus) {
if (!hasFocus) {
searchView.setIconified(true);
}
}
});
Here is my code. The onKey() method is never called when typing into the search box. Am I doing something wrong in setting up the listener? I have a breakpoint in the onKey() method, which is how I know it doesn't fire.
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.locations_map_menu, menu);
ActionBar ab = getActionBar();
ab.setBackgroundDrawable(getResources().getDrawable(R.drawable.actionbar));
ab.setDisplayShowTitleEnabled(false);
SearchView searchView = (SearchView) menu.findItem(R.id.menu_search).getActionView();
searchView.setOnKeyListener(new OnKeyListener() {
#Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
return true; // This code never fires
}
});
return true;
}
Add an OnQueryTextListener, see my answer here
final SearchView.OnQueryTextListener queryTextListener = new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextChange(String newText) {
// Do something
return true;
}
#Override
public boolean onQueryTextSubmit(String query) {
// Do something
return true;
}
};
searchView.setOnQueryTextListener(queryTextListener);
if you want to get a key on serach view
you can use below code
TextView searchText = (TextView) searchView.findViewById(android.support.v7.appcompat.R.id.search_src_text);
searchText.setOnKeyListener(new View.OnKeyListener() {
#Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
return false;
}
});