为什么 android.widget.SearchView 没有在单击时展开,而是将图标移到左侧?

Why is the android.widget.SearchView not expanding on single click and instead moves the icon to left side?

我在 MaterialToolbar 中使用 android.widget.SearchView 并且还在菜单资源文件中设置了正确的属性。但是当我单击搜索图标时,它不会展开。相反,搜索图标会移到左侧。再次单击它时,它会展开,但搜索图标仍然出现在 EditText 中。


布局文件

<com.google.android.material.appbar.AppBarLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <com.google.android.material.appbar.MaterialToolbar
        android:id="@+id/toolbar"
        style="@style/Widget.MaterialComponents.Toolbar.Primary"
        android:layout_width="match_parent"
        android:layout_height="?actionBarSize"
        app:title="@string/app_name" />

</com.google.android.material.appbar.AppBarLayout>

菜单文件

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
      xmlns:app="http://schemas.android.com/apk/res-auto">

    <item
        android:id="@+id/action_search"
        android:title="@string/action_search"
        android:icon="@drawable/ic_search"
        app:showAsAction="ifRoom|collapseActionView"
        app:actionViewClass="android.widget.SearchView" />

</menu>


点击前

点击后

SearchView hint

尽管文档建议使用框架 SearchView,但我总是发现 support/androidx SearchView 与库组件一起使用效果更好 – 例如,AppCompatActivityMaterialToolbar,等等——虽然我不确定到底是什么导致了这些小故障。事实上,在这里使用 androidx.appcompat.widget.SearchView 代替 android.widget.SearchView 来代替 actionViewClass 在扩展时摆脱了那个错位的搜索图标。

但是,SearchView 中的 AutoCompleteTextView 仍然有一个类似的搜索图标作为提示,因为它没有以正确的样式结束。我最初预计将 Toolbar 设置为支持 ActionBar 会将其与 children 的其他相关样式集成,但似乎 SearchView 的样式,因为出于某种原因,通常在 <*Toolbar> 上设置 ThemeOverlay.*.ActionBar 作为 ActionBar.

虽然大多数来源似乎表明各种 ThemeOverlay.*.ActionBar 样式仅调整 colorControlNormal 属性,但它们实际上也将 searchViewStyle 设置为适当的 Widget.*.SearchView.ActionBar 值,因此添加适当的叠加层非常重要。例如,为了与 androidx 版本保持一致:

<com.google.android.material.appbar.MaterialToolbar
    android:id="@+id/toolbar"
    android:theme="@style/ThemeOverlay.MaterialComponents.Dark.ActionBar"
    ... />

这也可以通过将其设置为 Activity 主题中的 actionBarTheme 来实现,但请注意,它可能会被 <*Toolbar> 本身的属性覆盖,就像 style="@style/Widget.MaterialComponents.Toolbar.Primary".

在给定的设置中一样

如果您不使用 Material 组件,也可以使用 ThemeOverlay.AppCompat 样式。如果您只使用平台 类,系统命名空间中也有类似的样式;例如,@android:style/ThemeOverlay.Material.Dark.ActionBar.


此答案的初始修订版手动删除了该提示图标,因为当时我并不知道给定的设置究竟是如何失败的。现在应该没有必要这样做,但如果您想进一步自定义,该示例只是将菜单 <item>app:actionViewClass 属性替换为 app:actionLayout 指向这个布局:

<androidx.appcompat.widget.SearchView
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/search_view"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:searchHintIcon="@null" />

searchHintIcon 设置是此处示例所需的全部设置,但您可以设置您想要的任何适用的 SearchView 属性。

如果您要走这条路,最好设置 style="@style/Widget.AppCompat.SearchView.ActionBar",其中包括 searchHintIcon 设置,并确保 SearchView 的整体样式正确,因为由 Artem Mostyaev 在下面的评论中建议。

以上方法对我不起作用。我不知道为什么但是尝试了这个并成功了。 通过 SearchView 引用搜索提示图标并将其可见性设置为 GONE:

ImageView icon = (ImageView) mSearchView.findViewById(androidx.appcompat.R.id.search_mag_icon);
icon.setVisibility(View.GONE);

然后添加这一行:

mSearchView.setIconified(false);