Простые Фрагменты Стека

Доброго времени суток, уважаемые читатели Хабра! Хочу представить вашему вниманию статью, основанную на моем опыте работы в Single Activity Architecture, в частности со стеком пользовательских представлений.

Когда я впервые познакомился с Single Activity Architecture, у меня было много вопросов: «Как я могу контролировать момент добавления и удаления фрагментовЭ», «Как фрагмент может удерживать кнопку «Назад»Э», «Можно ли запустить фрагмент по результатуЭ», «Как понять, когда пользователь вернулся к фрагментуЭ» и т. д. Первый вопрос почти тривиален.

Вы можете создать единый класс навигации, которому можно передать менеджер фрагментов и использовать его с помощью функции перехода экрана.

Вторая проблема также частично решается путем уведомления класса навигации о нажатии кнопки «Назад».

Но в этом случае навигатор начинает быть чем-то большим, чем просто хранителем путей; в этом появляется логика, которая, на мой взгляд, абсолютно неоправданна.

Но должен ли кто-то в системе управлять движениями вперед и назад? Также есть некоторые сложности с возвратом пользователя во фрагмент. Одним из наиболее критичных, на мой взгляд, является повторный вызов onCreateView. Как мы все знаем, существует собственное представление в виде View. Я также думаю, ни для кого не секрет, что эта операция достаточно прожорлива.

В результате получаем класс с большим количеством логики переходов, созданием разного рода фрагментов, сомнительными вставками «очень полезного функционала» в методы обработки обратной навигации (если пользователь что-то добавил на предыдущем экране, это необходимо добавить в список).

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

Разумное решение — делегировать часть функциональности другим частям системы.

Таким образом, в моей программе появилась сущность стека фрагментов.

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

Для меня, как дизайнера, основной проблемой был жизненный цикл добавляемых/удаляемых фрагментов.

Также определенной проблемой было завершение фрагмента результатом и отправка результата его потребителю.

К счастью, решение было найдено довольно быстро.

Для внутренней логической структуры я выбрал немного улучшенный стек: слоеный пирог.

Идея состоит в том, что слои наслаиваются на корку.

Корочку нашего абстрактного пирога можно считать точкой входа в приложение (основной фрагмент, домашнюю страницу и т. д.).

Слои, в свою очередь, обладают следующими свойствами:

  • Когда вы добавляете слой, первое, что вы делаете, это создаете его.

    Затем его аккуратно укладывают на корж или пласт, который находится сверху.

  • При удалении слоя слой ниже становится видимым, а удаляемый слой отбрасывается.

    И действительно, зачем нам промазанный кремом слой?

Отойдя от красивого примера, добавление — это транзакция, состоящая из сокрытия предыдущего фрагмента и добавления нового.

Также в этой операции я добавил к скрытому фрагменту уведомление о том, что пользователь его покинул, и ограничение на размер стека.

Операция удаления более витиеватая, поэтому все будет описано подробнее.

Логику, отвечающую за отправку результата из фрагмента провайдера во фрагмент, имеет смысл вынести в отдельный класс.

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

Это своего рода аналог onActivityResult. Если изобразить все вышеперечисленное на схеме, то это будет выглядеть так Схема

Простые фрагменты стека



Фрагменты производительности

Чтобы обеспечить эффективность, я создал отдельный класс ResultUtils и интерфейс ResultableFragment. Потребителем может быть любой фрагмент, расширяющий интерфейс ResultableFragment. Этот интерфейс состоит из одной функции void onFragmentResult(final int requestCode, Final int resultCode, Final Bundle data).

Эта функция является аналогом onActivityResult.

   

public interface ResultableFragment {

Теги: #разработка Android #разработка Java #разработка Android
Вместе с данным постом часто просматривают: