主题自定义未加载 MenuInflater

Theme customization is not loaded with MenuInflater

我注意到主题自定义和充气器出现意外行为。

我有以下自定义主题 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>        

以及搜索的配置

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>

当我从方法 onCreateOptionsMenu 创建 SearchView 时,自定义未加载

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
}

但是,如果我为片段创建一个带有 SearchView a 的布局,例如:

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>

在片段中

public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    // Inflate the layout for this fragment
    return inflater.inflate(R.layout.fragment_explorer, container, false);
}

然后我的SearchView有自定义

在第一种情况下,布局由 MenuInflater 膨胀,在第二种情况下,由 LayoutInflater 膨胀。 我读到,如果上下文不像 ApplicationContext 那样了解主题,则不会加载自定义。但就我而言,两者都使用 Activity 作为上下文。

您知道菜单 Inflater 缺少自定义设置是否有原因吗?

更新

实际上这两种情况的上下文都不是我想的来自同一个实例。即使使用 this.getMenuInflater() 从 Activity 中检索到 MenuInflaterSearchView 中的上下文(由 MenuInflater 提供)也是 ContextThemeWrapper 的实例,而LayoutInflater 上下文是我的 activity GeoCodleActivity。所以这似乎是行为不一样的原因。所以现在的问题是如何在 MenuInflater 中获取 Activity 作为上下文。我按照@pskink 的建议尝试了 new MenuInflater (this)(感谢您的建议)。这次我有正确的主题,但是当我检索 SearchView 时它为空。我在 SearchView 构造函数中添加的断点甚至没有触发

    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();

使用 SupportMenuInflater 而不是 MenuInflater 它按预期工作。当然我的活动扩展 AppCompatActivity

所以在 onCreateOptionsMenu

MenuInflater menuInflater = new SupportMenuInflater(this);
menuInflater.inflate(R.menu.options_menu, menu);

您可以创建自定义 ThemedSearchView

class ThemedSearchView @JvmOverloads constructor(
context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
, defTheme: Int = R.style.CustomSearchView
) : SearchView(ContextThemeWrapper(context, defTheme), attrs, defStyleAttr)

您可以将自己的主题应用到 SearchView