As for your published code, this is the result:
As you can see, there are two fields on the left: the widget container and the zoom icon. This is why you have more white space than another title bar. And the menu items are pushed out of the toolbar, which, I think, is the default SearchView ActionView
when it is not a CollapseActionView
, so it fills the parent element.
From the source of the SearchView
widget and its layout abc_search_view.xml, I tried to remove additional fields and not click on other elements outside the toolbar.
But after many manipulations, I think you should use your own widget and / or custom layout. Or play with setIconifiedByDefault(true)
, which removes the enlargement icon and its additional margin and use setMaxWidth(MAX_SIZE)
, where MAX_SIZE
calculated dynamically on Integer.MAX_VALUE - (SIZE_OF_A_MENU_ITEM * NB_OF_MENU_ITEMS)
... But it takes a lot of work. So using a custom layout might be a solution.
However, there is a possible way to save the appcompat widget , some small workarounds. First, you can use CollapseActionView
to avoid hitting other items.
<item ... app:actionViewClass="android.support.v7.widget.SearchView" app:showAsAction="always|collapseActionView"/>
And in order to support your requirements, you must expand it when you initialize it:
final SearchView searchView = (SearchView) MenuItemCompat.getActionView(item); MenuItemCompat.expandActionView(item);
Remember that you need to use setOnActionExpandListener()
to close the window if you do not want to collapse the item. This sentence will give you this result:
More extra fields, right? Thus, you should get the container and the enlargement icon with their identifiers (which you can find in abc_search_view.xml
... but let's save some time: they are R.id.search_edit_frame
and R.id.search_mag_icon
). You can delete their fields using this method:
private void changeSearchViewElements(View view) { if (view == null) return; if (view.getId() == R.id.search_edit_frame || view.getId() == R.id.search_mag_icon) { LinearLayout.LayoutParams p = (LinearLayout.LayoutParams) view.getLayoutParams(); p.leftMargin = 0; // set no left margin view.setLayoutParams(p); } if (view instanceof ViewGroup) { ViewGroup viewGroup = (ViewGroup) view; for (int i = 0; i < viewGroup.getChildCount(); i++) { changeSearchViewElements(viewGroup.getChildAt(i)); } } }
Calling it in a stream:
final SearchView searchView = (SearchView) MenuItemCompat.getActionView(item); ... searchView.post(new Runnable() { @Override public void run() { changeSearchViewElements(searchView); } });
Here's the conclusion:
Finally, to get the line below the field, there is a possible workaround using 9-patch drawable and set as the background. You can easily find instructions on Google. Thus, the condition will be:
private void changeSearchViewElements(View view) { ... if (view.getId() == R.id.search_edit_frame || view.getId() == R.id.search_mag_icon) { LinearLayout.LayoutParams p = (LinearLayout.LayoutParams) view.getLayoutParams(); p.leftMargin = 0;
From the OP comment below, the underline can also be done with the following expression:
searchView.findViewById(android.support.v7.appcompat.R.id.search_src_text) .setBackgroundResource(R.drawable.abc_textfield_search_default_mtrl_alpha);
After these workarounds, as I said, it would be easier to use a custom layout. But if you want to keep the default SearchView widget, this might help.