Android 4.1.2を使用しています。 ActionBar
にSearchViewウィジェットがあります。 Android開発者サイトのSearchView.OnQueryTextListener
に関するドキュメントには、「ユーザーがクエリを送信するときに呼び出されます。これは、キーボードのキーを押すか、送信を押すことにより、onQueryTextSubmit
ボタン。"
検索クエリが空の場合、これは発生しません。 ListViewの検索フィルターをクリアするために空のクエリで起動するためにこれが必要です。これはバグですか、何か間違っていますか?
これはバグではありません。 ソースコード は、null値と空の値に対して意図的にチェックします。
private void onSubmitQuery() {
CharSequence query = mQueryTextView.getText();
if (query != null && TextUtils.getTrimmedLength(query) > 0) {
ただし、ユーザーが検索EditTextをクリアすると、OnQueryTextChangeコールバックを使用してListViewのフィルター可能項目をクリアできるはずです。
より簡単な回避策を講じる: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;
}
});
私は同じ問題を抱えていて、次の解決策になりました:custom SearchView
+ OnQueryTextListener.onQueryTextChange
カスタム検索ビュー:
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でテスト済み。
SearchViewでも同じ問題が発生しました。ガイドに示されているSearchViewのスタイル設定で構成される私のソリューション http://novoda.com/blog/styling-the-actionbar-searchview/ およびEditTextのOnEditorActionListenerの設定( どのようにトリガーしますかユーザーがEnterを押したときのアクション? )これは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;
}});
他の人が言及したように、この動作は意図的なものです。 OnQueryChangeListener
の解決策をあきらめ、SearchViewのOnEditorActionListener
にEditText
を実装することで回避策を決定しました。これはR.id.search_src_text
を使用するためのハンドルを取得できます。 SearchViewのsetImeOptions
をEditorInfo.IME_ACTION_SEARCH
にすると、キーボードの検索ボタンのクリックを処理できます。 this SO answer を参照してください。
空のクエリはサポートされていないため、同じ問題が発生しました。 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();
}
}
お役に立てれば。
古いスレッドですが、別の解決策を見つけました(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", "")
にオーバーライドすることだけです
これは非常にダーティなハックですただし、期待どおりに正しく動作し、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);
}
次のように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」ボタンでテキストをクリアしてもクエリをクリアします
この動作を上書きすることはできません。回避策は、ユーザーが検索ビューを終了したときにフィルターをクリアすることです。
これには OnCloseListener を使用できます。ただし、開発対象の最小APIレベルによっては、これも問題を引き起こす可能性があります。
私の場合、API検索でキーワードとして使用されていたため、ユーザーがクエリをクリアできるようにしたかったため、最も簡単なアイデアは次のとおりでした。
searchView.setOnSearchClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
userQuery = "";
}
});
ここで、userQueryは検索などに使用される私の変数です。
それが誰かを助けることを願っています:)
もう1つのオプションは、TextWatcherを使用して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ファイルに当てはまりますが、この答えのポイントではありません。これは私が使用することを選択した回避策であり、他の人を自由に使用してください