Ich verwende Android 4.1.2. Ich habe ein SearchView-Widget für eine ActionBar
. Die Dokumentation zu SearchView.OnQueryTextListener
von der Android-Entwicklerseite gibt an, dass onQueryTextSubmit
ausgelöst wird, wenn "beim Abfragen des Benutzers die Abfrage erfolgt. Dies kann durch einen Tastendruck auf der Tastatur oder durch das Drücken einer Übermittlungstaste verursacht werden."
Dies ist nicht der Fall, wenn die Suchabfrage leer ist. Ich brauche dies, um eine leere Abfrage auszulösen, um den Suchfilter einer ListView zu löschen. Ist das ein Fehler oder mache ich etwas falsch?
Es ist kein Fehler, der source code prüft absichtlich auf null und leere Werte:
private void onSubmitQuery() {
CharSequence query = mQueryTextView.getText();
if (query != null && TextUtils.getTrimmedLength(query) > 0) {
Sie sollten jedoch in der Lage sein, den OnQueryTextChange-Callback zu verwenden, um die Filtermöglichkeiten Ihrer ListView zu löschen, wenn der Benutzer die Suche EditText löscht.
eine einfachere Umgehung ist folgende: Verwenden Sie onQueryTextChange, aber nur wenn es leer ist.
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;
}
});
Ich hatte das gleiche Problem und endete mit der folgenden Lösung: custom SearchView
+ OnQueryTextListener.onQueryTextChange
Benutzerdefinierte Suchansicht:
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;
}
}
Aktion anlegen und Rückruf setzen:
@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);
}
Und zuletzt der Hörer:
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.
}
};
Getestet an ABS 4.3.
Ich hatte das gleiche Problem mit SearchView. Meine Lösung besteht darin, SearchView wie im Guide http://novoda.com/blog/styling-the-actionbar-searchview/ - zu stylen und OnEditorActionListener für EditText ( Wie stelle ich beim Benutzer eine Aktion aus hat die Eingabetaste gedrückt? ) Welcher Teil der SearchView war dies:
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;
});
Wie andere bereits erwähnt haben, ist dieses Verhalten beabsichtigt. Ich gab eine Lösung für OnQueryChangeListener
auf und entschied mich für eine Problemumgehung, indem ich OnEditorActionListener
in der EditText
von SearchView implementierte, die Sie mit R.id.search_src_text
behandeln können. Solange Sie setImeOptions
von SearchView EditorInfo.IME_ACTION_SEARCH
sind, können Sie mit einem Klick auf die Tastatur-Suchschaltfläche klicken. Siehe diese SO Antwort für weitere Details.
Ich hatte das gleiche Problem, da leere Abfragen nicht unterstützt werden, musste ich ActionBarSherlock herunterladen und dann die onSubmitQuery () - Methode ändern.
So sieht mein onSubmitQuery () jetzt aus
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();
}
}
Hoffe das hilft.
Ich kann das einfach erreichen, indem ich setOnQueryTextListener auf folgende Weise implementiert:
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;
}
});
Wo sich meine loadLocalData-Methode befindet
//query my DB
products = ProductDAO.findByIdList(idList);
LinearLayoutManager layoutManager = new LinearLayoutManager(this);
listView.setLayoutManager(layoutManager);
listView.setAdapter(<YOURADAPTER>)
Diese Lösung löscht Ihre Abfrage, selbst wenn Sie den Text mit der Schaltfläche "X" löschen
Es ist ein alter Thread, aber ich habe eine andere Lösung gefunden (Kotlin-Code, funktioniert aber auch in Java):
override fun onQueryTextChange(newText: String?): Boolean {
if(newText == null || newText.isEmpty())
searchView.setQuery("\u00A0", false)
return true
}
\u00A0
ist ein Zeichen, das wie ein Leerzeichen aussieht, aber vom Code her nicht. Mit anderen Worten ist SearchView nicht leer. Eine leere Zeichenfolge oder " "
würde nicht funktionieren, da die Basisanwendung von SearchView den Befehl trim verwendet. Soweit ich weiß, können Benutzer \u00A0
-Zeichen nicht eingeben.
Dann müssen Sie getQuery in Ihrer benutzerdefinierten Suchansicht mit return super.getQuery.replace("\u00A0", "")
überschreiben
Sie können dieses Verhalten nicht überschreiben. Eine Problemumgehung kann darin bestehen, den Filter zu löschen, wenn ein Benutzer die Suchansicht beendet.
Sie können den OnCloseListener dafür verwenden. Dies kann jedoch auch zu Problemen führen, abhängig von dem Mindest-API-Level, für den Sie entwickeln.
In meinem Fall wollte ich dem Benutzer lediglich ermöglichen, seine Abfrage zu löschen, da sie bei der API-Suche als Schlüsselwort verwendet wurde.
searchView.setOnSearchClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
userQuery = "";
}
});
wobei userQuery meine Variable ist, die für die Suche usw. verwendet wird.
Hoffe es hilft jemandem :)
Dies ist ein sehr schmutziger Hack , er funktioniert jedoch wie erwartet und aktiviert die Übergabeaktion, auch wenn in SearchView kein Text eingegeben (oder eingegeben und dann bearbeitet) wird.
Er erhält nachdenklich Zugriff auf den Aktions-Listener des inneren TextView-Editors, verpackt ihn in einen benutzerdefinierten Listener, wo er den Aufruf an den Handler delegiert, und legt ihn schließlich als Aktionslistener für die innere TextView fest.
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);
}
Eine andere Option ist das manuelle Auslösen der onQueryTextChange-Methode über einen TextWatcher:
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;
}
}
Dies alles gilt für alle hier aufgegebenen Standard-XML-Dateien, darum geht es nicht in dieser Antwort. Dies ist eine Problemumgehung, für die ich mich entschieden habe, andere zu verwenden