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();
Related
I have the search view at the top of my layout I want when I( clicked the button the cursor should show in the search bar.
here is the image enter image description here
Create an ID for the SearchView and use this code to create actions within it.
#Override
public boolean onCreateOptionsMenu(Menu menu){
getMenuInflater().inflate(R.menu.beneficiary_search, menu);
MenuItem search = menu.findItem(R.id.searchicon);
SearchView searchView = (SearchView) search.getActionView();
searchView.requestFocus()
searchView.setOnQueryTextListener(this);
return true;
}
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 am creating android application and I'm trying to respect as much as possible the latest Android usability standards. In particular, I am preparing the user interface using the navigation drawer, and I'm trying to ensure compatibility with 2.1+ Android versions. To appreciate the problem, the project consists of:
A main activity;
A navigation drawer;
Four fragments (with their associated layouts).
The problem I'm experiencing occurs when opening the navigation drawer: although each Fragment has its specific menu, when I open the navigation drawer it is added to the nav drawer menu. I tried in several ways (invalidateOptionMenu(), menu.clear(), manipulating functions isDrawerOpen() and isDrawerClose() and more), but I cannot remove the Fragment's menu when opening the navigationdrawer.
These are some snippets of my code, much of it generated by Android Studio, the IDE I'm using:
In main activity:
#Override
public boolean onCreateOptionsMenu(Menu menu) {
if (!mNavigationDrawerFragment.isDrawerOpen()) {
// Only show items in the action bar relevant to this screen
// if the drawer is not showing. Otherwise, let the drawer
// decide what to show in the action bar.
getMenuInflater().inflate(R.menu.global, menu);
restoreActionBar();
return true;
}
return super.onCreateOptionsMenu(menu);
}
where "global" is a simple menu with a classical "ic_action_overflow".
And in my fragments I've:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
#Override
public void onPrepareOptionsMenu(Menu menu) {
super.onPrepareOptionsMenu(menu);
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
inflater.inflate(R.menu.fragment1, menu);
}
(It's the same of the other Fragments).
Someone can give me some advice on how to act?
I faced the same problem using the boilerplate code generated by Android Studio and got it working by modifying the menu in NavigationDrawerFragment.onPrepareOptionsMenu() (in my case, I wanted to clear the menu altogether):
#Override
public void onPrepareOptionsMenu(Menu menu) {
if (mDrawerLayout != null && isDrawerOpen()) {
menu.clear();
}
}
This is roughly how the options menu is recreated:
NavigationDrawerFragment, which is generated by the IDE, calls supportInvalidateOptionsMenu() when the drawer is opened or closed.
onCreateOptionsMenu gets called: The hosting activity and each of the added fragments gets a chance to contribute menu items.
onPrepareOptionsMenu gets called: Again, the hosting activity and each of the added fragments get a chance to modify the menu.
The fragments are iterated in the order they were added. There is no way to stop the chain of calls midway in steps 2. and 3.
So the idea is to let NavigationDrawerFragment do last-minute changes to the menu in its onPrepareOptionsMenu and no other fragments.
If you need to let other fragments do something in onPrepareOptionsMenu, then you may have to setup those other fragments so they can determine if the drawer is open or not and change their behavior accordingly. This may mean perhaps adding a isDrawerOpen method to the hosting activity or passing in the drawer identifiers to the fragment like it's done in NavigationDrawerFragment.setup().
In your fragment onCreate, add this :
setHasOptionsMenu (true);
And then hide through onPrepareOptionsMenu. e.g.
#Override
public void onPrepareOptionsMenu(Menu menu) {
super.onPrepareOptionsMenu(menu);
menu.findItem(R.id.action_settings).setVisible(false);
}
If you've implemented the navigation drawer the way Android Studio sets it up for you in its example code with a NavigationDrawerFragment, you should have two xml to start with main.xml (activity wide actionbar menu items) and global.xml (global items). I then added a fragment specific menu which adds items to the "activity menu items" as long as the drawer is closed...
Activity:
#Override
public boolean onCreateOptionsMenu(Menu menu) {
if (!mNavigationDrawerFragment.isDrawerOpen()) {
// Only show items in the action bar relevant to this activity
// if the drawer is not showing. Otherwise, let the drawer
// decide what to show in the action bar.
getMenuInflater().inflate(R.menu.main, menu);
this.menu = menu;
restoreActionBar();
return true;
}
return super.onCreateOptionsMenu(menu);
}
NavigationDrawerFragment
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
// If the drawer is open, show the global app actions in the action bar.
// See also showGlobalContextActionBar, which controls the top-left area
// of the action bar.
if (mDrawerLayout != null && isDrawerOpen()) {
inflater.inflate(R.menu.global, menu);
showGlobalContextActionBar();
}
super.onCreateOptionsMenu(menu, inflater);
}
and in your fragments add as you've described above
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
// Add fragment specific action bar items to activity action bar items.
// Activity wide items are in main.xml
// Visible action bar items if navigation drawer is visible/open
// are in global.xml
super.onCreateOptionsMenu(menu, inflater);
if (!mNavigationDrawerFragment.isDrawerOpen()) {
inflater.inflate(R.menu.fragment_menu, menu);
}
}
Check out this answer here: https://stackoverflow.com/a/18135409/2558344. Its basically using a boolean to clear items in the navigation drawer and vice versa. But alternatively, you could declare Menu menu as a private variable in your class and use it as: onCreateOptionsMenu(menu, MenuInflater inflater).
Then check in your fragments onStop(), onPause() if it's displaying items or not, if yes then clear them, like:
if (menu != null)
menu.clear();
I use searchview in my Android app and I would like to add a button that user presses to start the search. Based on what I read on the Internet, I can use setSubmitButtonEnabled to invoke a submit button instead of putting a button in the layout file. Here's my code:
public void setSubmitButtonEnabled (boolean enabled) {
}
I put my setSubmitButtonEnabled in the menu inflater as below:
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.mylist, menu);
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);
setSubmitButtonEnabled(true);
return true;
}
Apparently I am not doing it right because when I launch my app, I don't see any submit button on the screen. What's missing or what's wrong in my code? Is the submit button supposed to appear on the keypad or on the screen? Thank you.
You need to call
searchView.setSubmitButtonEnabled(true)
Why would you create your own version with no body and expect it to do anything?
For this use
searchView=findViewById(R.id.search_box);
searchView.setSubmitButtonEnabled(true);
For submit button icon use
app:goIcon="#drawable/ic_arrow_forward_black_24dp"
For SearchView default expanded
app:iconifiedByDefault="false"
I currently have a SearchView in my app's ActionBar (of which I am populating from an XML layout file) and I am trying to force it to only take numeric input. I've tried setting the android:inputType="number" attribute in XML, but it has no effect.
Does anyone know the source of this problem?
The XML menu resource:
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="#+id/search"
android:title="#string/menu_search"
android:actionViewClass="android.widget.SearchView"
android:icon="#drawable/ic_menu_search_holo_light"
android:inputType="number" />
</menu>
setInputType on a searchView was introduced in API 14. To set it to number try :
searchView.setInputType(InputType.TYPE_CLASS_NUMBER);
If you're setting it in a compatibility library fragment, you need to use SearchViewCompat.setInputType(View searchView, int inputType):
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.searchable, menu);
MenuItem searchMenuItem = menu.findItem(R.id.action_search);
if (searchMenuItem != null) {
SearchView searchView = (SearchView) searchMenuItem.getActionView();
if (searchView != null) {
SearchViewCompat.setInputType(searchView, InputType.TYPE_CLASS_TEXT|InputType.TYPE_TEXT_VARIATION_POSTAL_ADDRESS);
}
}
}
When using SearchView from android.support.v7.widget you can use:
searchView.setInputType(InputType.TYPE_CLASS_NUMBER);
This isn't exactly an answer, but keep in mind that the usefulness of input type filters can be contingent on the IME you're using; some keyboards don't readily obey these input types... I learned that the hard way. :(
With that in mind, have you tried using other input types to see if they'll stick? If they do stick, it's likely an IME issue. If they don't, it's likely an issue with the way in which you're trying to enforce the input type.
Now, for a shot at an answer:
You might try, in onCreateOptionsMenu, doing a lookup by ID of that menu item, casting to a SearchView, and setting the input type in code:
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater menuInflater = getMenuInflater();
menuInflater.inflate(R.menu.default_menu, menu);
if (MyApplication.SUPPORTS_HONEYCOMB) { // quick check for API level
// If we have the honeycomb API, set up the search view
MenuItem searchItem = menu.findItem(R.id.search);
SearchView search = (SearchView) searchItem.getActionView();
// your code here. something like:
search.setInputType(InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_VARIATION_NORMAL);
// you also likely want to set up your search listener here.
}
// I'm using ActionBarCompat, in which case
// calling super after populating the menu is necessary here to ensure that the
// action bar helpers have a chance to handle this event.
return super.onCreateOptionsMenu(menu);
}
For Kotlin users
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
menuInflater.inflate(R.menu.menu_main, menu)
val searchMenuItem = menu?.findItem(R.id.menu_search)
val searchView = searchMenuItem?.actionView as SearchView
searchView.inputType = InputType.TYPE_CLASS_NUMBER
return true
}