android - 在 android 工具栏中正确实现 SearchView

标签 android android-toolbar searchview

我对 android 工具栏中的 searchview 实现有疑问。

  1. 空白填充太大。
  2. 我不想隐藏其他 Action ,但这些 Action 是 与 SearchView 重叠。
  3. SearchView 的下划线不可见

我该如何解决上述问题?

enter image description here

menu.xml

<?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/car_num"
        android:icon="@drawable/ic_search_white_24dp"
        app:actionViewClass="android.support.v7.widget.SearchView"
        app:showAsAction="always" />

    <item
        android:id="@+id/action_add_client"
        android:icon="@drawable/ic_account_multiple_plus"
        android:title="@string/action_add_client"
        app:showAsAction="always" />
</menu>

fragment

@Override
public void onCreateOptionsMenu(final Menu menu, MenuInflater inflater) {
    inflater.inflate(R.menu.menu_fragment_reg_vehicles, menu);

    final MenuItem item = menu.findItem(R.id.action_search);
    searchView = (SearchView) MenuItemCompat.getActionView(item);
    searchView.setQueryHint("Search");
    searchView.setMaxWidth(Integer.MAX_VALUE);
    searchView.setIconifiedByDefault(false);
    searchView.setOnQueryTextListener(this);
    searchView.setOnCloseListener(new SearchView.OnCloseListener() {
        @Override
        public boolean onClose() {
            setItemsVisibility(menu, item, true);
            return false;
        }
    });
    searchView.setOnSearchClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            setItemsVisibility(menu, item, false);
            searchView.requestFocus();
        }
    });
}

最佳答案

关于您发布的代码,这是输出:

Toolbar with SearchView AppCompat by default

如您所见,有两个左边距:小部件的容器和放大图标。这就是为什么你有一个比另一个有标题的窗口大的空白空间。菜单项被推到工具栏之外,我认为它是默认的 SearchView ActionView 而不是 CollapseActionView 所以它会填充父项。

来自 SearchView 小部件及其布局的来源 abc_search_view.xml ,我试图删除多余的边距并避免将其他项目推到工具栏之外。
但经过多次操作,我猜你必须使用自定义小部件和/或自定义布局。或者使用 setIconifiedByDefault(true) 删除放大图标及其额外边距,并使用 setMaxWidth(MAX_SIZE) 其中 MAX_SIZE 是动态计算的通过 Integer.MAX_VALUE - (SIZE_OF_A_MENU_ITEM * NB_OF_MENU_ITEMS)... 但它需要大量的工作才能白费。因此,使用自定义布局可能是解决方案。

但是,有一种可能的方法来保留 appcompat 小部件,一些小的解决方法。首先,为避免推出其他项目,您可以使用 CollapseActionView

<item
    ...
    app:actionViewClass="android.support.v7.widget.SearchView"
    app:showAsAction="always|collapseActionView"/>

为了维护您的需求,您必须在初始化时扩展它:

final SearchView searchView =
            (SearchView) MenuItemCompat.getActionView(item);
MenuItemCompat.expandActionView(item);

请注意,如果您不想折叠项目,则必须使用 setOnActionExpandListener() 来关闭窗口。此建议将为您提供结果:

Toolbar with SearchView AppCompat expanded

还有额外的边距,对吧?因此,您必须通过它们的 ID 检索容器和放大图标(您可以在 abc_search_view.xml 中找到...但让我们节省一些时间:它们是 R.id.search_edit_frame R.id.search_mag_icon)。您可以使用此方法删除它们的边距:

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

在线程中调用:

final SearchView searchView =
            (SearchView) MenuItemCompat.getActionView(item);
...
searchView.post(new Runnable() {
        @Override
        public void run() {
            changeSearchViewElements(searchView);
        }
    });

这是输出:

Toolbar with SearchView AppCompat without left margin

最后,要在字段下方设置线条,有一个可能的解决方法,即使用 9 补丁可绘制对象并将其设置为背景。您可以在 Google 上轻松找到操作方法。所以条件将是:

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; // set no left margin
        view.setLayoutParams(p);

    } else if (view.getId() == R.id.search_src_text) {
        AutoCompleteTextView searchEdit = (AutoCompleteTextView) view;
        searchEdit.setBackgroundResource(R.drawable.rect_underline_white);
    }
    ...
}

从下面OP的评论来看,下划线的字段也可以用下面的语句来完成:

searchView.findViewById(android.support.v7.appcompat.R.id.se‌​arch_src_text)
        .setBa‌​ckgroundResource(R.d‌​rawable.abc_textfiel‌​d_search_default_mtr‌​l_alpha);

在这些解决方法之后,正如我所说,使用自定义布局可能会更容易。但如果您想保留默认的 SearchView 小部件,这可能会有所帮助。

关于android - 在 android 工具栏中正确实现 SearchView,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41248031/

相关文章:

java - WebView 中视频的全屏按钮不起作用

android - 工具栏布局未定义

java - fragment 删除/添加问题搜索 View

android - SharedPreferences setChecked 崩溃

android - fitsSystemWindows 在 NavigationView 中的自定义布局中不起作用

android - 如何在工具栏中制作圆角菜单?

android - Toolbar+SearchView+textSelection = 文本选择栏位置错误

android - 从 SearchView 小部件中删除默认搜索图标

java - 如何使用AdapterView.INVALID_ROW_ID?

Android Material Design 工具栏自定义操作菜单未正确对齐