android.support.v4.widget.SearchViewCompat example? - android

I am trying to use SearchViewCompat with ActionBarSherlock in an API 8 app.
public boolean onCreateOptionsMenu(Menu menu) {
MenuItem item = menu.add("Search")
.setIcon(isLight ? R.drawable.ic_search_inverse : R.drawable.ic_search)
.setActionView(R.layout.collapsible_edittext);
item.setShowAsAction(
MenuItem.SHOW_AS_ACTION_ALWAYS |
MenuItem.SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW);
// To use SearchViewCompat, I need to add it to the Menu item as well:
View searchView = SearchViewCompat.newSearchView(this);
// ...
SearchViewCompat.setOnQueryTextListener(...);
// ...
item.setActionView(searchView);
Please note that both the top and bottom code needs to call setActionView(). Does that mean it is not possible to do search?

If you are using the ActionBarSherlock Library ver 4.2, you can replace the API 11 SearchView Widget with a ActionBarSherlock SearchView Widget to make it backward compatible:
search.xml
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="#+id/menu_search"
android:icon="#drawable/ic_action_search"
android:title="#string/description_search"
android:orderInCategory="0"
android:actionViewClass="com.actionbarsherlock.widget.SearchView"
android:showAsAction="ifRoom|collapseActionView" />
</menu>
Activity class
//IMPORTANT!!!
import com.actionbarsherlock.widget.SearchView;
...
#Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
getSupportMenuInflater().inflate(R.menu.search, menu);
setupSearchMenuItem(menu);
return true;
}
private void setupSearchMenuItem(Menu menu) {
MenuItem searchItem = menu.findItem(R.id.menu_search);
if (searchItem != null) {
SearchView searchView = (SearchView) searchItem.getActionView();
if (searchView != null) {
SearchManager searchManager =
(SearchManager) getSystemService(SEARCH_SERVICE);
searchView.setSearchableInfo(
searchManager.getSearchableInfo(getComponentName()));
}
}
}
}

What is the actual problem? SearchViewCompat will return null for pre-HC devices since the SearchView widget does not exist. This means you will have to provide your own custom action view that imitates the HC SearchView.
You can also backport the SearchView component from the Android sources and use that.
Otherwise, you can just use the existing search interfaces Android has, in which case for HC+ devices you use the action view to perform a search but on Froyo and Gingerbread devices the user clicks on the search icon and a search bar animates from the top.
Hope this helps.

At some point in your Activity:
public class HomeActivity extends SherlockFragmentActivity implements
SearchView.OnQueryTextListener {
// ...
SearchView searchView = (com.actionbarsherlock.widget.SearchView)
actionBarCustom.findViewById(R.id.search);
SearchManager sm = (SearchManager)getSystemService(SEARCH_SERVICE);
searchView.setSearchableInfo(sm.getSearchableInfo(getComponentName()));
searchView.setSubmitButtonEnabled(true);
searchView.setOnQueryTextListener(this);
And then filter your list adapter:
#Override
public boolean onQueryTextSubmit(String query) {
return true;
}
#Override
public boolean onQueryTextChange(String newText) {
mAdapter.getFilter().filter(newText.trim());
return false;
}
This way, your list adapter must implement filterable.

Better to use MenuItemCompat,I think this is helpful for you
getMenuInflater().inflate(R.menu.main, menu);
MenuItem searchItem = menu.findItem(R.id.search);
SearchManager searchManager =(SearchManager)getSystemService(Context.SEARCH_SERVICE);
SearchView searchView = (SearchView)MenuItemCompat.getActionView(searchItem);
SearchableInfo info = searchManager.getSearchableInfo(getComponentName());
searchView.setSearchableInfo(info);

Related

Make the SearchView do searches

I have a SearchView up and ready, here is the code I use in the java file of the page that has the SearchView:
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.options_menu, menu);
// Associate searchable configuration with the SearchView
SearchManager searchManager =
(SearchManager) getSystemService(Context.SEARCH_SERVICE);
SearchView searchView =
(SearchView) menu.findItem(R.id.search).getActionView();
searchView.setSearchableInfo(searchManager.getSearchableInfo(
new ComponentName(getApplicationContext(), SearchableActivity.class)));
return true;
}
My goal is now to let this SearchView search through a site full of TextViews. Every TextView contains one word. Is it possible to make the SearchView find the TextView that contains the word i just typed in? If so, how? If not, how can I make it happen in another way?
Kind regards,
Julian
The SearchView doesn't do any search at all, it's a simple widget for inputting the keywords, show recently used keywords, etc. You should implement your "search model" to find the content, and display it somewhere you want.
I guess what you are trying to do is search through text inside TextViews defined inside your layout.
I am assuming here that the text source is a String Array/ArrayList (TextViewData) in a file "Data.java.
You can give this a try:
1) Make the activity/fragment implement SearchView.OnQueryTextListener
2) Create an empty ArrayList to store search entry results.
private ArrayList<Data> mSearchItems
3) Add this line to the code where you initialize your SearchView
searchView.setOnQueryTextListener(this);
4) Override the following methods:
i) Method called on submit:
#Override
public boolean onQueryTextSubmit(String query) {
//Call a user defined mathod to handle the search.
handleSearch(query, Data.TextViewData)
}
ii) Method called on changing the text in the search box
#Override
public boolean onQueryTextChange(String query) {
handleSearch(query, Data.TextViewData)
}
5)
private void handleSearch(String Query, ArrayList<Data> queryList){
mSearchItems.clear();
for(Data data : queryList){
if(data.textviewone.toLowerCase().contains(Query.toLowerCase()) ||
data.textviewtwo.toLowerCase().contains(Query.toLowerCase()))
mSearchItems.add(data);
//You can then swap the recycler view (if being used) or hide other text views and display only the one being searched for (in case of a match)
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
SearchView searchView = (SearchView) MenuItemCompat.getActionView(menu.findItem(R.id.menu_search));
SearchManager searchManager = (SearchManager) getSystemService(Activity.SEARCH_SERVICE);
searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
// Setting up custom search button icon
int searchImgId = android.support.v7.appcompat.R.id.search_button; // I used the explicit layout ID of searchview's ImageView
ImageView v = (ImageView) searchView.findViewById(searchImgId);
v.setImageResource(R.drawable.ic_search_black);
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String query) {
// Do operation
return true;
}
#Override
public boolean onQueryTextChange(String newText) {
return false;
}
});
return true;
}
menu_search.xml
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:appcompat="http://schemas.android.com/apk/res-auto">
<item
android:id="#+id/menu_search"
style="#android:style/Widget.ActionButton"
android:icon="#drawable/ic_search_black"
android:title="#string/search"
appcompat:actionViewClass="android.support.v7.widget.SearchView"
appcompat:showAsAction="always" />
</menu>

Android SearchView: Show suggestions in a custom view, not listview

I am implementing a searchview for my app. Here is how i set my searchview:
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.options_menu, menu);
this.menu = menu;
// Associate searchable configuration with the SearchView
SearchManager searchManager =
(SearchManager) getSystemService(Context.SEARCH_SERVICE);
MenuItem searchItem = menu.findItem(R.id.search);
SearchView searchView = (SearchView) MenuItemCompat.getActionView(searchItem);
searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String query) {
return false;
}
#Override
public boolean onQueryTextChange(String query) {
loadHistory(query);
return true;
}
});
return true;
}
I want to show search suggestions to user when user starts typing. I can do this using a listview:
private void loadHistory(String query) {
// query db etc...
SearchManager manager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
final SearchView search = (SearchView) menu.findItem(R.id.search).getActionView();
search.setSuggestionsAdapter(new ExampleAdapter(this, cursor, items));
}
But suppose I do not want to show search suggestions as a listview, and show them in a custom view, where I can add some more stuff to my layout other then just search suggestions. For example, I want to show the following custom view instead of suggested searches listview:
How can I do that? There is a function for setting suggestions adapter, setSuggestionsAdapter(adapter), but I could not find a function like setCustomSuggestionsView(view).
Thanks.
I think what you need is a recycler view for your results. Please see this answer for more information. A recycler view gives you all the freedom layout wise. To use more viewtypes see this post. Hope this helps. I am not familliar enough with your case from your description.

SearchView does not iconify

In my app I am using an android.support.v7.widget.SearchView (from support v7 library) to provide search from action bar.
I setup this view in MainActivity, with the following code:
MainActivity.java
#Override
public boolean onCreateOptionsMenu(Menu menu) {
this.menu = menu;
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.main, menu);
SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
SupportMenuItem searchMenuItem = (SupportMenuItem) menu.findItem(R.id.menu_search);
SearchView searchView = (SearchView) MenuItemCompat.getActionView(searchMenuItem);
searchView.setQueryRefinementEnabled(true);
searchView.setIconifiedByDefault(true);
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
// OnQueryTextListener body
...
});
searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
return super.onCreateOptionsMenu(menu);
}
Then in a Fragment i need to ensure that the SearchView is collapsed:
MyFragment.java
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
MenuItem searchMenuItem = menu.findItem(R.id.menu_search);
SearchView searchView = (SearchView) MenuItemCompat.getActionView(searchMenuItem);
searchView.clearFocus(); // Try to prevent SearchView to steal focus. No luck!
searchView.setIconified(true);
}
#Override
public void onResume() {
super.onResume();
setHasOptionsMenu(true);
// other stuff
}
The problem is that not only the SearchView does not collapse (I tried also with MenuItemCompat.collapseActionView(searchMenuItem) with no success: it returns always false), but also the SearchView "steals" focus at every fragment transaction (e.g. replace one fragment with another), so when the "new" fragment is displayed, the SearchView has focus, so it shows its suggestions.
I also noticed that if I do not call setHasOptionsMenu then the problem of "stealing focus" does not occur.
Is there something I am doing wrong?

SearchView (Support) in FragmentActivity always null

I've started messing around with fragments, as my app on tablets could be using space more efficiently.
Now, in my old app, I had a SearchView in the actionbar menu, that would show on ifRoom. I'm using the same code, but now the SearchView item is always null. I'm not looking for changing the menu items depending on active fragments or whatever, I just need the SearchView to function from the FragmentActivity.
FragmentActivity:
#Override
public boolean onCreateOptionsMenu(Menu menu)
{
getMenuInflater().inflate(R.menu.main, menu);
MenuItem searchItem = menu.findItem(R.id.svPet);
this.svPet = (SearchView)MenuItemCompat.getActionView(searchItem);
if(this.svPet != null)
{
this.svPet.setInputType(InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS);
this.svPet.setOnQueryTextListener(this);
}
return true;
}
main.xml:
<?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/svPet"
app:actionViewClass="android.support.v7.widget.SearchView"
app:showAsAction="ifRoom"
android:title="#string/search"
android:titleCondensed="#string/search">
</item>
...Some more items that are never shown as action and work correctly
</menu>
So, whenever the menu is being created, this.svPet stays null, the searchview is not displayed in the bar (even when there's more than enough room), and when I click on the item from the menu, my application crashes, saying there's a nullpointer on
this.svPet.setIconified(false);
in
#Override
public boolean onOptionsItemSelected(MenuItem item)
Any ideas on what might be wrong? I'm probably overlooking something, but I just don't see what's wrong at the moment. Thanks in advance :)
some ideas
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu, menu);
MenuItem searchItem = menu.findItem(R.id.action_search);
//SearchView searchView = (SearchView) MenuItemCompat.getActionView(searchItem);
SearchView searchView = (SearchView) searchItem.getActionView();
if (searchView != null) {
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String s) {
// do something with s, the entered string
query = s;
Toast.makeText(getApplicationContext(), "String entered is " + s,Toast.LENGTH_SHORT).show();
return true;
}
#Override
public boolean onQueryTextChange(String s) {
return false;
}
});
}
return super.onCreateOptionsMenu(menu);
}
menu.xml
<item android:id="#+id/action_search"
android:orderInCategory="5"
android:title="Search"
android:icon="#drawable/ic_action_search"
android:showAsAction="ifRoom|collapseActionView"
android:actionViewClass="android.widget.SearchView" />
</menu>
So... after some digging I found that when using MenuItemCompat in combination with FragmentActivity, getActionView(searchItem) returns null. I think this is a bug in the support library, so I'll have to submit a bugreport for that. (Done, https://code.google.com/p/android/issues/detail?id=76141&thanks=76141&ts=1410649918)
My workaround:
Instead of
this.svPet = (SearchView)MenuItemCompat.getActionView(searchItem);
I used
this.svPet = new SearchView(this);
MenuItemCompat.setShowAsAction(searchItem, MenuItemCompat.SHOW_AS_ACTION_IF_ROOM);
MenuItemCompat.setActionView(searchItem, this.svPet);
--Edit--
After some more looking around, I found that you can just use ActionBarActivity instead of FragmentActivity, as ActionBarActivity extends FragmentActivity. When using that, you can use
this.svPet = (SearchView)MenuItemCompat.getActionView(searchItem);
as usual.

Change text in searchview

I'm having a Searchview that is immediately focused ( the client wants this ). The text in the search balk is always an icon glass with text Search hint!.
How can I change the text?
I tried with
SearchView searchView = (SearchView) menu.findItem(R.id.action_search).getActionView();
searchView.setQueryHint("TEST");
Then the text appears real quick and then changes back to the default of android.
<item
android:id="#+id/action_search"
android:icon="#drawable/ic_action_search"
android:title="#string/action_search"
android:visible="false"
app:actionViewClass="android.support.v7.widget.SearchView"
app:showAsAction="collapseActionView|ifRoom" />
EDIT:
This is my creation:
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
menu.findItem(R.id.action_beneficiaries).setVisible(false);
menu.findItem(R.id.action_search).setVisible(query == null);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
if (query == null) {
// Associate searchable configuration with the SearchView
SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
SearchView searchView = (SearchView) menu.findItem(R.id.action_search).getActionView()
searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
searchView.setIconifiedByDefault(false);
}
}
return true;
}
#Override
public boolean onPrepareOptionsMenu(Menu menu) {
// called from menu
if (getCallingActivity() == null) {
menu.findItem(R.id.action_accounts).setVisible(true);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
menu.findItem(R.id.action_transaction).setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
} else {
menu.findItem(R.id.action_transaction).setVisible(false);
}
} else {
// called from New Transaction
menu.findItem(R.id.action_transaction).setVisible(false);
}
return super.onPrepareOptionsMenu(menu);
}
According to your xml, you are using the Support Library. Therefore, you need to retrieve your item with this following:
MenuItem searchItem = (MenuItem) menu.findItem(R.id.action_search);
SearchView searchView = (SearchView) MenuItemCompat.getActionView(searchItem);
Then, you will be able to change the text of the hint with searchView.setQueryHint() and even its color with setHintTextColor.

Categories

Resources