在android工具栏中正确实现SearchView

时间:2016-12-20 17:26:18

标签: android android-toolbar searchview

我在android工具栏中的searchview实现有问题。

  1. 空的空间填充太大了。
  2. 我不想隐藏其他动作,但这些动作是 与SearchView重叠。
  3. SearchView的下划线不可见
  4. 我如何解决上述问题?

    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>
    

    片段

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

1 个答案:

答案 0 :(得分:4)

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

Toolbar with SearchView AppCompat by default

如您所见,左边距有两个:窗口小部件的容器和放大图标。这就是为什么你有一个空的空间大于另一个带标题的窗口。菜单项被推到工具栏外面,我认为,当它不是ActionView时,它是默认的SearchView 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_frameR.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-patch drawable并将其设置为背景。您可以轻松找到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小部件,这可能有所帮助。