Создаём объект Gallery, который содержит ListView в качестве элемента

5 апреля 2011 г.

Введение

После внимательного изучения официального руководства по созданию Gallery View я задался вопросом, а можно ли создать такую галерею (Gallery), которая содержала бы в себе не только картинки, но и всяческие поля, кнопочки. В голову сразу же пришел ответ: конечно можно! Благодаря гибкости, которую предоставляют слои, можно создавать сколь-угодно сложные иерархические структуры. Чтобы жизнь уж совсем мёдом не казалась, было решено засунуть в Gallery списки ListView.
К концу этой статьи будет создан проект, который объединяет в себе крупицы информации, разбросанные по всей сети. Цель этой статьи — объединить эту информацию и создать шпаргалку для дальнейших разработок.

Начало

Для начала необходимо изучить официальное руководство и создать проект Gallery View. Собственно этот проект мы и будем модифицировать.

Замена слоя Gallery

Итак, у нас есть готовый проект для демонстрации Gallery. Для того, чтобы сделать красивое пролистывание, как в Gallery, но при этом со своими элементами (списками, кнопочками и прочим) необходимо вместо картинки подсунуть свой слой.
Для этого создаём новый слой: gallery_layout.xml
Корневым элементом нашего слоя будет ListView:

ListView

Т.к. в качестве корневого элемента мы выбрали ListView, то для него придётся написать свой элемент (т.е. описать слой и сделать свой адаптер). По хорошему, это тянет на отдельную статью, но задача здесь аналогичная: подставить в ListView свой адаптер и написать отдельный слой для элемента списка.
Создаём слой для элемента списка list_view_layout_item.xml:

list_view_layout_item.xml

Теперь создаём класс ListViewAdapter, унаследованный от BaseAdapter. Всё аналогично туториалу для GalleryView, только вместо картинок мы подставляем свой слой, об этом, кстати, можно прочитать здесь.
Исходный код для ListViewAdapter:

ListViewAdapter
ListViewAdapter 2

Теперь у нас есть слой элемента галереи gallery_layout с корневым элементом ListView и адаптер для него ListViewAdapter. Нам необходимо теперь вместо картинок в классе ImageAdapter подсунуть только что созданный слой. Для этого в функции public View getView() мы просто заменим инициализацию элемента View, установим ему наш собственный слой и наш собственный адаптер.

public View getView()

Как видно наш адаптер принимает в конструкторе массив, который надо отобразить. Значит надо заполнить ещё информацию для отображения. Пусть это будет массив строк (у нас же список в конце концов). Добавим локальную переменную в класс ImageAdapter:

ImageAdapter

Запускаем проект и убеждаемся, что прокрутка по вертикали есть, а по горизонтали – нет.

Работа над ошибками

Теперь было бы очень полезно, если бы наши списки пролистывались. Проблема состоит в том, что GalleryView и ListView пересекаются в попытках перехватить сигнал MotionEvent. В данном случае ListView доминирует и Gallery просто не получает события MotionEvent, поэтому прокрутки по горизонтали нет. А хотелось бы.
Для этого надо перенаправлять события на объект Gallery. Создаём отдельный объект GestureDetector и направляем все события на него:

MotionEvent

Аналогично поступаем и при инициализации ListView в Gallery:

ListView в Gallery

Здесь parent – экземпляр главного класса, для того, чтобы его получить, придётся переписать конструктор:

parent

Запускаем наше приложение и видим, что теперь горизонтальная прокрутка работает, но заметны подёргивания, подрагивания и прочие мелкие пакости. Это возникает из-за того, что то лист, то галерея перехватывают событие MotionEvent.

Последние штрихи

Теперь нам надо избавиться от лагов, которые возникают при «борьбе» ListView и GalleryView за событие MotionEvent. Для этого расширим класс Gallery, назовём его BetterGallery:

BetterGallery

Преимущества нового класса перед старым в том, что он «отфильтровывает» необходимые события.
Теперь перепишем главный класс:

И соответственно main.xml, чтобы отобразить нашу новую, улучшенную галерею:

main.xml

Запускаем приложение и радуемся почти безглючной прокрутке.
Проект данного приложения можно скачать здесь.

Заключение

Конечно, не всё так безоблачно и прокрутка всё равно подёргивается, подглючивает и т.п. Но нет предела совершенству. Буду рад, если кто-нибудь поможет мне довести её до ума.

Теги: рубрика Программирование
  • Похожие статьи
  • Предыдущие из рубрики