Я создаю окно поиска для своего приложения, где пользователь может вводить данные в поле, а заголовки возвращаются в recyclerView под полем поиска. Заголовки находятся в файле php на сервере - результаты фильтруются в соответствии с тем, что пользователь вводит в поле поиска.
Так, например, одно из заголовков в моем файле php:
red onions
Если пользователь набирает red, recyclerView показывает, как он набирает:
red cabbage
red mushrooms
red onions
Эта часть работает правильно.
Но когда пользователь набирает red o, в recyclerView ничего не отображается. Тогда как, собственно, должен появиться red onions.
Я уверен, что это происходит, потому что в моем приложении я разбиваю заголовки php на отдельные слова, поэтому пробел (" ") между red и onions вызывает проблему.
Есть идеи, как я могу это восстановить?
Причина, по которой я разбиваю заголовок на слова в первую очередь, заключается в том, что если пользователь вводит второе слово, onions, red onions будет отображаться в результате в recyclerView, а не вообще ничего.
Вот мой код:
@Override
public Filter getFilter() {
return new Filter() {
@Override
protected FilterResults performFiltering(CharSequence charSequence) {
//the text entered in the search box
String charString = charSequence.toString();
//if searchbox is empty, show the whole list
if (charString.isEmpty()) {
categoryListFiltered = categoryList;
} else {
List<Category> filteredList = new ArrayList<>();
for (Category row : categoryList) {
//split the php title into separate words
String[] title_in_php = row.getName().split(" ");
//for every split word
for (String split_title : title_in_php) {
//if the search term entered is a whole word in the title
if (split_title.toLowerCase().startsWith(charString.toLowerCase())) {
filteredList.add(row);
}
}
}
categoryListFiltered = filteredList;
}
FilterResults filterResults = new FilterResults();
filterResults.values = categoryListFiltered;
return filterResults;
}
@Override
protected void publishResults(CharSequence charSequence, FilterResults filterResults) {
categoryListFiltered = (ArrayList<Category>) filterResults.values;
notifyDataSetChanged();
}
};
}
спасибо, но если я это сделаю, то в представлении ресайклера будут отображаться только заголовки, начинающиеся с поискового запроса. Если пользователь набирает «лук», ничего не отображается.
Тогда попробуйте row.getName().contains(charString).
Предполагая, что «красный лук» эквивалентен «красный лук», вам также придется разделить введенную строку charString и объединить поиск с помощью AND.
@AndrewS При этом, если поисковый запрос находится в любой части заголовка, результаты появляются в recyclerView. Например, «ion» возвращает «лук». Ищем только слова целиком.
что, если пользователь набирает «лук-лук»?
С "луком-луком" ничего не будет отображаться, и это правильно, потому что в базе данных нет заголовка с таким названием.
Может быть проще, если вы разместите более полные тестовые данные и ожидаемый результат.




После того, как вы ввели red o, он сначала проверит red и добавит row в filterList, потому что charString начинается с red, но проверка o не добавит row в filterList, потому что charString не начинается с o.
Попробуйте это (на основе комментариев):
if (split_title.toLowerCase().startsWith(charString.toLowerCase())) {
filteredList.add(row);
}
else if (row.getName().contains(charString.toLowerCase()) {
if (!filteredList.contains(row)) {
filteredList.add(row);
}
}
if для проверки split_title (например, red) - filterList.add (row);
else if проверит, содержит ли rowcharString (целая строка, например, red o) - filterList.add (строка);
if (!filteredList.contains(row)) просто проверяет, есть ли строка в списке. Если нет, то добавьте его. (Чтобы избежать дублирования)
Другой способ - разделить charString:
String[] charString= charSequence.toString().split(" ")
и повторить его:
for (int i=0; i<charString.length; i++) {
for (int n=0; n<title_in_php.length; n++) {
if (split_title.toLowerCase().startsWith(charString.toLowerCase()) || charString[i].toLowerCase() == title_in_php[n].toLowerCase() || row.getName().contains(charString.toLowerCase()) {
if (!filteredList.contains(row)) {
filteredList.add(row);
}
}
}
}
поэтому он проверит, начинается ли charString с title_in_phpИЛИ ЖЕ, если charString = title_in_phpИЛИ ЖЕ, если row содержит charString, проверяя список title_in_php на charString
[красный] начинается с [красный лук]ИЛИ ЖЕ[красный] = [красный лук]ИЛИ ЖЕ[красный лук] содержит [красный o]
Отличная, приятная работа. Я внес несколько небольших изменений, которые вскоре добавлю к вашему ответу выше, но в целом это решило проблему, tx.
Код разбивается на
" ", который не включен в String []. Попробуйтеrow.getName().startsWith(charString);