У меня есть активность, которая ищет набор изображений.Изображения отображаются в галерее.Существует EditText, где пользователь может ввести поисковый запрос.Когда пользователь вводит текст в EditText, галерея фильтруется в соответствии с введенным текстом.
Я сделал SearchResultAdapter extends BaseAdapter implements Filterable
, который работает в принципе нормально.Если пользователь вводит текст, данные в адаптере фильтруются.Я зарегистрировал результаты: это работает до сих пор.Затем я вызываю notifyAdapterSetChanged, чтобы галерея отображала обновленный набор данных.На самом деле вызывается notifyAdapterSetChanged, а галерея получает запрос, так как он вызывает мои адаптеры getCount () (я записал все вызовы).
Установка значения «0» приводит к сбою приложения из-за исключения IndexOutOfBoundsException, как я ожидаю, когда в галерее нет элементов.Тем не менее в галерее отображаются все изображения, которые были в нем ранее.
Проблема заключается в следующем: если набор данных пуст (т. Е. Пользователь ввел поисковый запрос, который не подходит ни к одному изображению), то галерея непоказать обновление.Галерея получает notifyAdapterSetChanged, запрашивает у адаптера счетчик элементов (который равен 0) и обновляет пределы прокрутки.Он не обновляет изображения, показанные в галерее.Я больше не могу прокручивать изображения, так как в основном нет изображений для отображения, но изображения не удаляются из галереи.Для пользователя это выглядит так, как будто галерея застыла.
Когда недопустимый поисковый термин удален (т. Е. Набор данных не пустой), галерея отображает правильные изображения.Также при некоторых условиях галерея отображает пустой список, например, когда приложение свернуто, а затем снова открыто.Однако я не могу воспроизвести условия, при которых галерея очищается (кроме сворачивания / повторного открытия приложения):
Я пытался сделать недействительной и requestLayout () галерею, но это не помогает.Кто-нибудь знает, как я могу заставить галерею обновлять список отображаемых изображений?
Вот сообщения журнала, когда пользователь вводит текст, который не соответствует изображению:
[SearchResultAdapter.SearchFilter] Results: 0
[SearchResultAdapter.SearchFilter] called notifyDataSetChanged()
[SearchResultAdapter.getCount()] getCount called: dateset size 0
[SearchResultAdapter.getCount()] getCount called: dateset size 0
Обратите внимание, как работает адаптерна самом деле вызывается галереей на размер набора данных
Инициализирующий код в упражнении:
final Gallery gallery = (Gallery) findViewById(R.id.search_results);
final SearchResultAdapter adapter = new SearchResultAdapter(this, gallery);
gallery.setAdapter(adapter);
EditText searchField = (EditText) findViewById(R.id.search_searchfield);
searchField.addTextChangedListener(new TextWatcher()
{
@Override
public void onTextChanged(CharSequence s, int start, int before,
int count)
{
// TODO unhardcode criterion
adapter.putFilterTerm(SearchCriteria.OFFERING, s.toString());
adapter.getFilter().filter(s);
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after)
{
// do nothing
}
@Override
public void afterTextChanged(Editable s)
{
// do nothing
}
});
И SearchResultAdapter (строки, которые не имеют значения, опущены):
public class SearchResultAdapter extends BaseAdapter implements Filterable
{
private Context context;
private Filter filter;
public void putFilterTerm(SearchCriteria key, String value)
{
filterTerms.put(key, value);
}
public boolean containsFilterTerm(SearchCriteria key)
{
return filterTerms.containsKey(key);
}
public String getFilterTerm(SearchCriteria key)
{
return filterTerms.get(key);
}
List<PageContainer> completeList = new ArrayList<PageContainer>();
List<PageContainer> currentList = new ArrayList<PageContainer>();
Map<SearchCriteria, String> filterTerms = new HashMap<SearchCriteria, String>();
View view;
public SearchResultAdapter(Context context, View gallery)
{
this.context = context;
this.view = gallery;
for (ContentPropertyContainer page : Model.getInstance()
.getRootContainer().getChildren())
{
completeList.add((PageContainer) page);
}
currentList.addAll(completeList);
}
@Override
public int getCount()
{
return currentList.size();
}
@Override
public Object getItem(int position)
{
return currentList.get(position);
}
@Override
public long getItemId(int position)
{
PageContainer item = currentList.get(position);
for (int i = 0; i < completeList.size(); ++i)
{
if (completeList.get(i) == item)
{
return i;
}
}
return -1;
}
@Override
public View getView(int position, View convertView, ViewGroup parent)
{
View listview = convertView;
// Code left out here tries to reuse the convertView
// like Romain Guy said in a Google I/O Talk
return listview;
}
private class ResultList
{
ResultList(List<PageContainer> results)
{
this.results = results;
}
List<PageContainer> results;
}
@Override
public Filter getFilter()
{
// implements Filterable
if (filter == null)
{
filter = new SearchFilter();
}
return filter;
}
private class SearchFilter extends Filter
{
SearchFilter()
{
// do nothing, needed for visibility
}
@Override
protected FilterResults performFiltering(CharSequence constraint)
{
FilterResults results = new FilterResults();
// Code left out here filters the list
return results;
}
@Override
protected void publishResults(CharSequence constraint,
FilterResults results)
{
if (results == null)
{
return;
}
if (results.values instanceof ResultList)
{
currentList = ((ResultList) (results.values)).results;
notifyDataSetChanged();
}
}
}
}
РЕДАКТИРОВАТЬ: установка видимости галереи на невидимую, а затем на видимую снова решила проблему.
view.post(new Runnable()
{
@Override
public void run()
{
view.setVisibility(View.INVISIBLE);
view.setVisibility(View.VISIBLE);
}
});
Есть ли лучшее решение?Это кажется мне довольно хакерским.