DrawerLayout: панели справа и слева одновременно

В недавней статье про DrawerLayout была мельком упомянута возможность сделать сразу две выезжающие панели — справа и слева, по образу и подобию клиента Google+ и ряда других приложений.

Правая панель в Google+
Правая панель в Google+

В качестве финальной, третьей части цикла статей (вторая часть была про скрещивание DrawerLayout и ActionBarSherlock) мы попробуем повторить в точности такое же поведение двух разных панелей на экране.

В чём проблемы?

Я полагаю, само добавление работоспособной правой панели не должно вызывать каких-либо вопросов. Во-первых, оно уже было описано в предыдущей статье по теме; во-вторых, даже если никаких статей не читать, несложно будет догадаться, что сводится задача к добавлению в DrawerLayout дочернего элемента с Gravity.END.

 

Но раз всё просто, так о чём же тогда этот текст?

Как водится — о нюансах. И немалочисленных.

Посмотрите на поведение того же клиента Google+, попробуйте пооткрывать drawer-ы и понаблюдать за приложением. Какие особенности мы видим?

Во-первых, индикатор-полосочка реагирует только на левую панель. Когда панель выезжает справа, полоски остаются безучастными. Теперь смотрим на поведение по умолчанию: индикатор радостно шевелится на любую панельку, левую или правую.

Во-вторых, виден только один drawer в единицу времени. Движением через край экрана можно вытащить либо левую, либо правую панель, но не две сразу. Теперь поведение по умолчанию: сразу две панели радостно ездят по экрану, налезают друг на друга, при сноровке и желании можно даже оставить открытыми обе.

В-третьих, попробуйте в «умолчательном» приложении ткнуть на индикатор, когда видны обе панели. Свалилось? И я о том же; комментарии тут даже не требуются. Google+, разумеется, лишён этого недостатка автоматически.

Вот именно этим и следовало бы заняться.

Решаем вопросы

Первое, с чего следовало бы начать — это блокировка появления второй панели когда открыта уже одна.

Очевидно, что тут потребуется слушатель состояния drawer-а и некоторый набор методов для блокировки ненужных панелей. То и другое у нас уже есть в готовом виде, но если с методом блокировки всё очевидно — его зовут setDrawerLockMode() — то со слушателем событий выходит небольшой конфуз: он уже занят экземпляром ActionBarDrawerToggle, выбросить который нельзя, а потому для него придётся написать небольшой анонимный дочерний класс.

В целом же логика получается простая: в наследнике ActionBarDrawerToggle мы ловим события drawer-а, смотрим какая панель открылась, и блокируем противоположную ей установкой режима DrawerLayout.LOCK_MODE_LOCKED_CLOSED. Если все панели закрылись, то разблокируем их: DrawerLayout.LOCK_MODE_UNLOCKED. А поскольку индикатор должен продолжать работать, то не забываем вызвать super-метод.

Но не решена ещё другая проблема: индикатор всё так же реагирует на правую панель. Заставить его бросить вредную привычку будет чуть сложнее: придётся проверять факт открывания правой панели, а потом запрещать работу индикатора если она ещё только собирается открываться. В этом нам поможет методика раннего перехвата — переопределение метода syncState() у ActionBarDrawerToggle, а также проверка на переход drawer-а в одно из активных состояний (т.е. какое угодно, кроме DrawerLayout.STATE_IDLE) при помощи метода onDrawerStateChanged().

Короткий полный код с комментариями, как всегда, скажет гораздо больше длинного поясняющего текста:

Теперь всё работает как надо! Учтите только, что заблокированный индикатор исчезает и заменяется индикатором по умолчанию. Потому не забудьте прописать в тему Activity те же самые «полосочки», чтоб пользователь не заметил разницы:

Теперь поведение становится полностью адекватным, и можно начать догонять и перегонять Google+ по всем остальным показателям.

Демо, примеры?

А демо-проект остаётся всё тем же, что и для предыдущих статей:

DemoDrawer.zip

Потому не удивляйтесь использованию там ActonBarSherlock — это код для соответствующей статьи. Ну а эта статья будет в цикле последней — хватит уже мучить DrawerLayout, есть много других интересных тем.

Но об этом уже как-нибудь в другой раз.

DrawerLayout: панели справа и слева одновременно
5, голосов: 5


Комментарии:

Один комментарий на «“DrawerLayout: панели справа и слева одновременно”»

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Капча (решите пример) *