I've noticed an unexpected behavior with my Theme customization and the inflater.
I have the following theme with the customization on the SearchView
<style name="GTheme" parent="Theme.AppCompat.Light.NoActionBar">
<item name="searchViewStyle">@style/SearchView</item>
<!--...-->
</style>
<style name="SearchView" parent="Widget.AppCompat.Light.SearchView">
<item name="iconifiedByDefault">false</item>
<item name="queryBackground">@color/white</item>
</style>
And for the configuration of the search
xml/searchable.xml
<searchable xmlns:android="http://schemas.android.com/apk/res/android"
android:label="@string/app_name"
android:icon="@android:drawable/ic_menu_search"
android:hint="@string/search_hint"/>
menu/options_menu.xml
<menu
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item android:id="@+id/search"
android:title="@string/search_view_title"
android:icon="@drawable/ic_search_white_24dp"
android:orderInCategory="100"
app:showAsAction="collapseActionView|ifRoom"
app:actionViewClass="android.support.v7.widget.SearchView"/>
</menu>
When I the SearchView
is created from the method onCreateOptionsMenu
the customization is not loaded
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
getMenuInflater().inflate(R.menu.options_menu, menu);
//Here I can already see that the costumization is missing with the debugger
//...
return true
}
However if I create a Layout with the SearchView
a for a fragment for example :
layout/fragment_explorer.xml
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:context="com.geocodle.android.ui.explorer.ExplorerFragment">
<android.support.v7.widget.SearchView
android:layout_gravity="center"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:iconifiedByDefault="true">
</android.support.v7.widget.SearchView>
</FrameLayout>
In the Fragment
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_explorer, container, false);
}
Then my SearchView
has the customization
In the first case the Layout is inflated by the MenuInflater and in the second case by the LayoutInflater. I read that in the case the context is not Theme aware like with ApplicationContext the customization is not loaded. But in my case both use the Activity as context.
Do you know if there is a reason why with the menu Inflater the customization is missing ?
Update
Actually the context is not from the same instance in both cases as I thought. Even if the MenuInflater
is retrieved from the Activity with this.getMenuInflater()
, the context in SearchView
(provided by the MenuInflater) is an instance of ContextThemeWrapper
wherea with the LayoutInflater
the context is my activity GeoCodleActivity
. So it seems it's the reason why the behavior is not the same. So now the question is how to get the Activity as context in the MenuInflater. I tried new MenuInflater (this)
as suggested by @pskink (thanks for your advices). This time I have the correct theme but then when I retrieve the SearchView it's null. The break point I added in the SearchView constructor is not even triggered
MenuInflater menuInflater = new MenuInflater(this);
menuInflater.inflate(R.menu.options_menu, menu);
//With this the SearchView is not null but Theme is not customized
//getMenuInflater().inflate(R.menu.options_menu, menu);
SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
//SearchAction has not Searchview
MenuItem searchAction = menu.findItem(R.id.search);
//searchView is null
SearchView searchView = (SearchView) searchAction.getActionView();
Using SupportMenuInflater
instead of MenuInflater
it works as expected. Of course My activivity extend AppCompatActivity
So in onCreateOptionsMenu
MenuInflater menuInflater = new SupportMenuInflater(this);
menuInflater.inflate(R.menu.options_menu, menu);