Android SearchView.OnQueryTextListener OnQueryTextSubmit未在空查询字符串上触发

问题描述 投票:24回答:12

我使用的是Android 4.1.2。我在ActionBar上有一个SearchView小部件。来自android开发者网站的SearchView.OnQueryTextListener文档指出,当用户提交查询时调用时会触发onQueryTextSubmit。这可能是由于键盘上的按键或按下提交按钮所致。

如果搜索查询为空,则不会发生这种情况。我需要这个来触发一个空查询来清除ListView的搜索过滤器。这是一个错误还是我做错了什么?

android searchview
12个回答
14
投票

这不是一个错误,source code故意检查null和空值:

private void onSubmitQuery() {
    CharSequence query = mQueryTextView.getText();
    if (query != null && TextUtils.getTrimmedLength(query) > 0) {

但是,当用户清除搜索EditText时,您应该能够使用OnQueryTextChange回调来清除ListView的过滤器。


0
投票

我可以通过以这种方式实现setOnQueryTextListener来实现:

SearchView searchView = (SearchView) menu.findItem(R.id.searchProductView).getActionView();
    searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
        @Override
        public boolean onQueryTextSubmit(String query) {
            return false;
        }

        @Override
        public boolean onQueryTextChange(String newText) {
            if (TextUtils.isEmpty(newText)) {
                loadLocalData(newText);
            }
            return true;
        }
    });

我的loadLocalData方法在哪里

//query my DB
products = ProductDAO.findByIdList(idList);
LinearLayoutManager layoutManager = new LinearLayoutManager(this);
listView.setLayoutManager(layoutManager);
listView.setAdapter(<YOURADAPTER>)

即使您使用“X”按钮清除文本,此解决方案也会清除您的查询


0
投票

在我的情况下,我只是想让用户清除他的查询,因为它在API搜索中用作关键字,所以最简单的想法是:

    searchView.setOnSearchClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            userQuery = "";
        }
    });

其中userQuery是我用于搜索的变量等。

希望它可以帮助别人:)


0
投票

这是一个旧线程,但我找到了另一种解决方案(Kotlin代码,但也适用于Java):

override fun onQueryTextChange(newText: String?): Boolean {
            if(newText == null || newText.isEmpty())
                searchView.setQuery("\u00A0", false)
            return true
        }

\u00A0是一个看起来像空间的角色,但在代码方面它不是。换句话说,SearchView不为空。空字符串或" "不起作用,因为基础SearchView使用修剪,加上用户可能想要搜索以空格结尾或以空格开头的文本。但据我所知,用户无法输入\u00A0字符。

然后,您需要做的就是在自定义SearchView中将getQuery覆盖到return super.getQuery.replace("\u00A0", "")


12
投票

我有一个更容易的解决方法:使用onQueryTextChange,但只有渲染,如果它是空的。

searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
            @Override
            public boolean onQueryTextSubmit(String query) {
                    renderList(true);
                    return false;
            }

            @Override
            public boolean onQueryTextChange(String newText) {
                    if (searchView.getQuery().length() == 0) {
                            renderList(true);
                    }
                    return false;
            }
    });

10
投票

我有同样的问题,最终得到以下解决方案:自定义SearchView + OnQueryTextListener.onQueryTextChange

自定义SearchView:

public class MySearchView extends SearchView {

private boolean expanded;

public MySearchView(Context context) {
    super(context);
}

@Override
public void onActionViewExpanded() {
    super.onActionViewExpanded();
    expanded = true;
}

@Override
public void onActionViewCollapsed() {
    super.onActionViewCollapsed();
    expanded = false;
}

public boolean isExpanded() {
    return expanded;
}
}

创建操作并设置回调:

@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
    super.onCreateOptionsMenu(menu, inflater);
    searchAction = menu.add(0, SEARCH_ACTION_ID, 0 , getString(R.string.action_search));
    searchAction.setShowAsAction(SHOW_AS_ACTION_ALWAYS | SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW);       
    searchView = new MySearchView(getSherlockActivity());
    searchView.setOnQueryTextListener(searchQueryListener);
    searchView.setIconifiedByDefault(true);
    searchAction.setActionView(searchView);
}

最后听众:

private OnQueryTextListener searchQueryListener = new OnQueryTextListener() {
    @Override
    public boolean onQueryTextSubmit(String query) {
        search(query);
        return true;
    }

    @Override
    public boolean onQueryTextChange(String newText) {
        if (searchView.isExpanded() && TextUtils.isEmpty(newText)) {
            search("");
        }

        return true;
    }

    public void search(String query) {
        // reset loader, swap cursor, etc.
    }

};

测试ABS 4.3。


9
投票

我在SearchView上遇到了同样的问题。我的解决方案包括样式SearchView,如指南http://novoda.com/blog/styling-the-actionbar-searchview/所示,并为EditText(How do I trigger an action when the user has hit enter?)设置OnEditorActionListener,它是SearchView的一部分,这是:

final SearchView searchView = (SearchView)findViewById(R.id.search);
int searchPlateId = searchView.getContext().getResources().getIdentifier("android:id/search_src_text", null, null);
EditText searchPlate = (EditText) searchView.findViewById(searchPlateId);
searchPlate.setOnEditorActionListener(new TextView.OnEditorActionListener() {
    @Override
    public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {

        if (actionId == EditorInfo.IME_ACTION_SEARCH) {
            //Do something
        }
        return false;

    });

3
投票

正如其他人所说,这种行为是故意的。我放弃了OnQueryChangeListener的解决方案,并决定通过在SearchView的OnEditorActionListener上实现EditText来解决这个问题,你可以使用R.id.search_src_text。只要您将SearchView的setImeOptions发送到EditorInfo.IME_ACTION_SEARCH,您就可以单击键盘搜索按钮。有关详细信息,请参阅this SO answer


1
投票

我有同样的问题,因为不支持空查询我必须下载并使用ActionBarSherlock然后修改onSubmitQuery()方法。

这就是我的onSubmitQuery()现在的样子

private void onSubmitQuery() {
     CharSequence query = mQueryTextView.getText();
     if (query == null) {query = "";}
     if (mOnQueryChangeListener == null
             || !mOnQueryChangeListener.onQueryTextSubmit(query.toString())) {
         if (mSearchable != null) {
             launchQuerySearch(KeyEvent.KEYCODE_UNKNOWN, null, query.toString());
             setImeVisibility(false);
         }
         dismissSuggestions();
     }
 }

希望这可以帮助。


1
投票

这是一个非常脏的黑客,但它按预期正常工作,即使没有在SearchView中输入(或输入然后编辑)文本,也可以启用提交操作。

它反过来获得对内部TextView编辑器动作侦听器的访问,将其包装在自定义侦听器中,在该侦听器中委托对处理程序的调用,最后将其设置为内部TextView的动作侦听器。

    Class klass = searchView.getClass();
    try {
        Field currentListenerField = klass.getDeclaredField("mOnEditorActionListener");
        currentListenerField.setAccessible(true);
        TextView.OnEditorActionListener previousListener = (TextView.OnEditorActionListener) currentListenerField.get(searchView);
        TextView.OnEditorActionListener newListener = new TextView.OnEditorActionListener() {
            @Override
            public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
                if (v.getText().length() == 0)
                    handleQuery("");
                return previousListener.onEditorAction(v, actionId, event);
            }
        };
        Field innerTextViewField = klass.getDeclaredField("mSearchSrcTextView");
        innerTextViewField.setAccessible(true);
        SearchView.SearchAutoComplete innerTextView = (SearchView.SearchAutoComplete) innerTextViewField.get(searchView);
        innerTextView.setOnEditorActionListener(newListener);
    } catch (Exception e) {
        throw new IllegalStateException(e);
    }

0
投票

您无法覆盖此行为。当用户退出搜索视图时,解决方法可能是清除过滤器。

你可以使用OnCloseListener。但是,这也会导致问题,具体取决于您正在开发的最低API级别。


0
投票

另一种选择是通过T​​extWatcher手动触发onQueryTextChange方法:

public class MyActivity extends Activity implements SearchView.OnQueryTextListener, TextWatcher {

    // Basic onCreate(Bundle) here

    @Override
    public boolean onCreateOptionsMenu (final Menu menu) {
        getMenuInflater().inflate(R.menu.myMenu, menu);

        final SearchView searchView = (SearchView) menu.findItem(R.id.action_search).getActionView();
        final SearchManager manager = (SearchManager) getSystemService(SEARCH_SERVICE);
        searchView.setSearchableInfo(manager.getSearchableInfo(getComponentName()));
        searchView.setOnQueryTextListener(this);

        final int resource_edit_text = searchView.getContext().getResources().getIdentifier("android:id/search_src_text", null, null);
        ((EditText) searchView.findViewById(resource_edit_text)).addTextChangedListener(this);

        return super.onCreateOptionsMenu(menu);
    }

    // Implementation of TextWatcher, used to have a proper onQueryTextChange (it doesn't update when the last character is removed)
    @Override
    public void beforeTextChanged (final CharSequence charSequence, final int start, final int count, final int after) {}

    @Override
    public void onTextChanged (final CharSequence charSequence, final int start, final int before, final int after) {}

    @Override
    public void afterTextChanged (final Editable editable) {
        if (editable.length() == 0)
            onQueryTextChange(editable.toString());
    }

    // Implementation of OnQueryTextChangeListener

    @Override
    public boolean onQueryTextChange (final String query) {
        // do stuff
        return false;
    }

    @Override
    public boolean onQueryTextSubmit (final String query) {
        // do stuff
        return false;
    }
}

这一切都与所有已在此处放弃的默认xml文件一起使用,这不是这个答案的要点。这是我选择使用的解决方法,随意使用其他人

© www.soinside.com 2019 - 2024. All rights reserved.