Галерея не показывает обновленный набор данных - PullRequest
0 голосов
/ 17 ноября 2011

У меня есть активность, которая ищет набор изображений.Изображения отображаются в галерее.Существует 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);
    }
});

Есть ли лучшее решение?Это кажется мне довольно хакерским.

...