I am working on an application that uses a SearchView embedded in the ActionBar. It works perfectly across the app, except for in one Activity. In this Activity, I can click the search icon to display the search view across the action bar, but as soon as I type anything into the search view, my text input is ignored (no text is displayed), and focus moves away from the search box.
The main difference between this activity and the others in my application is that this activity has tabs that are implemented using TabActivity. I am wondering if that is the cause, and if anyone has a potential solution.
This is the code for the SearchView:
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu, menu);
SearchView searchView = (SearchView) menu.findItem(R.id.menu_search).getActionView();
searchView.setSubmitButtonEnabled(true);
searchView.setOnQueryTextListener(queryTextListener);
searchView.setQueryHint("product search");
return true;
}
final SearchView.OnQueryTextListener queryTextListener = new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextChange(String newText) {
return true;
}
#Override
public boolean onQueryTextSubmit(String query) {
_listControl = new ListControl(_thisProduct,query);
_listControl.startGetData();
return true;
}
};
This is the setup of my tabbed activity. Tabs switch between different views.
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.product);
//set up tabs
mTabHost = getTabHost();
mTabHost.addTab(mTabHost.newTabSpec("tab_test1").setIndicator("Info").setContent(R.id.productLayout));
mTabHost.addTab(mTabHost.newTabSpec("tab_test2").setIndicator("Specs").setContent(R.id.specLayout));
mTabHost.addTab(mTabHost.newTabSpec("tab_test3").setIndicator("Reviews").setContent(R.id.reviewLayout));
mTabHost.addTab(mTabHost.newTabSpec("tab_test4").setIndicator("Buy").setContent(R.id.textView4));//
mTabHost.setCurrentTab(0);
mTabHost.getTabWidget().getChildAt(0).getLayoutParams().height = 40;
mTabHost.getTabWidget().getChildAt(1).getLayoutParams().height = 40;
mTabHost.getTabWidget().getChildAt(2).getLayoutParams().height = 40;
mTabHost.getTabWidget().getChildAt(3).getLayoutParams().height = 40;
I am definite that the SearchView should work with a tabbed activity and will try and let you know very soon. Meanwhile could you please try and use ViewPager instead of the tabbed activity you have which works with fragments or as an option ActionBar itself provides functionality to display tabs. Do lemme know how it goes.
Related
I'm trying to use one searchview from actitivity toolbar menu, to filter three fragments attached to it (It's a tabbed activity) at the same time and categorizing the results in the different fragments . Kind of like the way Instagram does theirs. I've tried inflating the onCreateOptionsMenu in each fragment, but this just starts a new instance of the search i.e (search icon is .istIconified(); I want the differnt tabs to show the query text of what ever was typed in it and perform the search at the same time.Can't seem to find this solution on SO, Any help or resource will be very much appreciated
Well it is possible.
first of all use "setOnQueryTextListener"
#Override
public void onPrepareOptionsMenu(Menu menu) {
super.onPrepareOptionsMenu(menu);
MenuItem item = menu.findItem(R.id.action_search);
SearchView searchView = (SearchView) MenuItemCompat.getActionView(item);
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String query) {
return false;
}
#Override
public boolean onQueryTextChange(String newText) {
Log.i("well", " this worked");
return false;
}
});
}
After that pass this string to currently selected fragment by calling fragment method from the activity. click here to check how to call fragment method from activity
From fragment method you can do anything which you want to do for.
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>
Recently I've added a tool for searching inside fragments. Some fragments have ListViews, so when a user types a search text, a ListView filters rows.
This is done with ActionBar after this tutorial.
I attached listeners from several fragments to a MainActivity, so when a user types a text at the top of the screen, it filters rows in a fragment. But in other fragments there is no need to search for anything, so a magnifying glass should be hidden.
However a magnifier is drawn at every screen. I also tried to not show it in activity and draw only in a fragment with this code:
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.main_invitro, menu);
menu.clear();
// Associate searchable configuration with the SearchView
SearchView searchView = (SearchView) menu.findItem(R.id.action_search).getActionView();
SearchManager searchManager = (SearchManager) getActivity().getSystemService(Context.SEARCH_SERVICE);
searchView.setSearchableInfo(searchManager.getSearchableInfo(getActivity().getComponentName()));
searchView.clearFocus();
super.onCreateOptionsMenu(menu,inflater);
}
But a magnifier stays in other fragments, also it is possible to type a text at the top.
Is there a correct way to show a magnifier only in some fragments?
I've got an answer at another forum.
In MainActivity:
boolean isVisible;
#Override
public boolean onPrepareOptionsMenu(Menu menu) {
super.onPrepareOptionsMenu(menu);
menu.findItem(R.id.action_search).setVisible(isVisible);
return true;
}
To update an ActionBar it should be called so:
invalidateOptionsMenu();
Normal Behavior:
When I request search in the SearchView widget on ActionBar, after
clicking soft-keyboard's search action button, the input text is
cleared from the SearchView.
My desired behavior:
I want the my input text to remain the same, when I perform search. How is that possible?
I have read official docs for SearchView, and guides from here, and also here, but haven't had any luck.
EDIT:
I discovered that this text reset happens whenever I scroll my ViewPager.
Try this:
mSearchView.setOnQueryTextListener(new SearchView.OnQueryTextListener()
{
#Override
public boolean onQueryTextSubmit(String query)
{
mSearchView.setQuery(query,false);
return false;
}
#Override
public boolean onQueryTextChange(String newText)
{
return false;
}
});
If your search widget calls another activity to handle the query, it gets cleared because the activity is newly created.
Therefore you need to set the query manually from 2 places:
onCreateOptionsMenu where you initialize your search widget
onNewIntent where you receive your query
Why from 2 places? Because if the search-handling activity is newly created, onNewIntent is called first and the search widget is not yet ready to be used. In that case save the query at onNewIntent and set it at onCreateOptionsMenu. Otherwise it can be directly set at onNewIntent.
Here's an example:
private String mQuery;
private SearchView mSearchView;
#Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
mQuery = intent.getStringExtra(SearchManager.QUERY);
if (mSearchView != null) {
mSearchView.setQuery(mQuery, false);
}
// Do something with the new query
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the actionbar items
getMenuInflater().inflate(R.menu.actionbar_items, menu);
// Get SearchView and set the searchable configuration
SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
mSearchView = (SearchView) menu.findItem(R.id.action_search).getActionView();
mSearchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
// Disable collapsing the search widget
mSearchView.setIconifiedByDefault(false);
// Set the query
mSearchView.setQuery(mQuery, false);
return true;
}
I used Android search widget in action bar. When I write my query and press on search button or done, everything works in my search part, but I want to remove that query in search field, or Resetting Search Widget (SearchView) value.
For example: if I write "test" after pressing search button I don't want to have this "test" in my search filed. Would you please let me know how can I remove my search query!
Thanks in advance!
I'm using SearchView widget from android
The method you are looking for is setQuery(), documented here:https://developer.android.com/reference/android/widget/SearchView.html#setQuery(java.lang.CharSequence, boolean)
Here's some example code which clears the search bar after a search is performed. You probably already have an implementation of onCreateOptionsMenu() in your activity or fragment, so just use the bits you are missing.
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.my_menu, menu);
// Find search item
MenuItem item = menu.findItem(R.id.my_search_item);
// Get search view attached to item
final SearchView searchView = (SearchView) mSearchItem.getActionView();
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String query) {
// Perform search here!
performSearch(query);
// Clear the text in search bar but (don't trigger a new search!)
searchView.setQuery("", false);
return true;
}
#Override
public boolean onQueryTextChange(String newText) {
return true;
}
});
}