Создайте подробный макет списка

Шаблон интерфейса "список-детали" — это двухпанельная компоновка, в которой одна панель отображает список элементов, а другая — подробную информацию об элементах, выбранных из списка.

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

Панель с подробной информацией отображается рядом со страницей списка.
Рисунок 1. При достаточно большом размере экрана панель с подробной информацией отображается рядом со списком.
После выбора элемента на весь экран открывается панель с подробной информацией.
Рисунок 2. При ограниченном размере экрана панель с подробной информацией (поскольку элемент выбран) занимает все пространство.

Реализуйте шаблон «Список-Подробности» с помощью NavigableListDetailPaneScaffold

NavigableListDetailPaneScaffold — это компонент, упрощающий реализацию макета «список-детали» в Jetpack Compose. Он является оберткой для ListDetailPaneScaffold и добавляет встроенную навигацию и анимацию возврата с автоматическим предсказанием.

Структура "список-детали" поддерживает до трех панелей:

  1. Панель списка : отображает набор элементов.
  2. Панель сведений : Отображает подробную информацию о выбранном элементе.
  3. Дополнительная панель ( необязательно ) : Предоставляет дополнительный контекст при необходимости.

Конструкция адаптируется в зависимости от размера окна:

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

Объявление зависимостей

NavigableListDetailPaneScaffold является частью библиотеки адаптивной навигации Material 3 .

Добавьте следующие три связанные зависимости в файл build.gradle вашего приложения или модуля:

Котлин

implementation("androidx.compose.material3.adaptive:adaptive")
implementation("androidx.compose.material3.adaptive:adaptive-layout")
implementation("androidx.compose.material3.adaptive:adaptive-navigation")

Классный

implementation 'androidx.compose.material3.adaptive:adaptive'
implementation 'androidx.compose.material3.adaptive:adaptive-layout'
implementation 'androidx.compose.material3.adaptive:adaptive-navigation'
  • адаптивный: низкоуровневые компоненты, такие как HingeInfo и Posture
  • adaptive-layout: Адаптивные макеты, такие как ListDetailPaneScaffold и SupportingPaneScaffold
  • adaptive-navigation: Компоненты для навигации внутри и между панелями, а также адаптивные макеты, поддерживающие навигацию по умолчанию, такие как NavigableListDetailPaneScaffold и NavigableSupportingPaneScaffold

Убедитесь, что ваш проект включает compose-material3-adaptive версии 1.1.0-beta1 или выше.

Включите функцию автоматического ввода жеста "назад"

Чтобы включить анимацию «Назад» с функцией прогнозирования в Android 15 или более ранних версиях, необходимо включить поддержку жеста «Назад» с функцией прогнозирования. Для этого добавьте android:enableOnBackInvokedCallback="true" в тег <application> или отдельные теги <activity> ` в файле AndroidManifest.xml . Дополнительную информацию см. в разделе «Включение жеста «Назад» с функцией прогнозирования» .

Если ваше приложение ориентировано на Android 16 (уровень API 36) или выше, функция предиктивного ответа "Назад" включается по умолчанию.

Основное использование

Реализуйте NavigableListDetailPaneScaffold следующим образом:

  1. Используйте класс, представляющий выбранное содержимое. Используйте класс Parcelable для поддержки сохранения и восстановления выбранного элемента списка. Используйте плагин kotlin-parcelize для генерации кода.
  2. Создайте объект ThreePaneScaffoldNavigator с rememberListDetailPaneScaffoldNavigator .

Этот навигатор используется для перемещения между панелями списка, подробной информации и дополнительных панелей. Объявив универсальный тип, навигатор также отслеживает состояние структуры (то есть, какой из MyItem отображается). Поскольку этот тип допускает послойное отображение, состояние может быть сохранено и восстановлено навигатором для автоматической обработки изменений конфигурации.

  1. Передайте навигатор в составной объект NavigableListDetailPaneScaffold .

  2. Передайте реализацию панели списка в NavigableListDetailPaneScaffold . Используйте AnimatedPane для применения анимации панели по умолчанию во время навигации. Затем используйте ThreePaneScaffoldNavigator для перехода к панели с подробной информацией, ListDetailPaneScaffoldRole.Detail , и отображения переданного элемента.

  3. Включите реализацию панели с подробной информацией в NavigableListDetailPaneScaffold .

После завершения навигации currentDestination содержит панель, на которую перешло ваше приложение, включая отображаемое в ней содержимое. Свойство contentKey имеет тот же тип, что и указанное в исходном вызове, поэтому вы можете получить доступ к любым данным, которые вам необходимо отобразить.

  1. При желании можно изменить defaultBackBehavior в NavigableListDetailPaneScaffold . По умолчанию в NavigableListDetailPaneScaffold используется PopUntilScaffoldValueChange для defaultBackBehavior .

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

BackNavigationBehavior

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

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

Рассмотрим следующие примеры:

  • Многооконный режим: Вы просматриваете электронное письмо (пункт 1) в панели с подробной информацией. Щелчок по другому электронному письму (пункт 2) обновляет панель с подробной информацией, но панели со списком и подробной информацией остаются видимыми. Нажатие кнопки «Назад» может привести к выходу из приложения или из текущего потока навигации.
  • Однопанельный режим: вы просматриваете пункт 1, затем пункт 2, нажатие кнопки «Назад» вернет вас непосредственно в панель со списком электронных писем.

Используйте это, если хотите, чтобы пользователи воспринимали четкие переходы между элементами интерфейса при каждом нажатии кнопки "Назад".

Изменение значения параметра навигации.
PopUntilContentChange

Такое поведение определяет приоритет отображаемого контента. Если вы просматриваете сначала Элемент 1, а затем Элемент 2, нажатие кнопки «Назад» вернет вас к Элементу 1, независимо от расположения элементов.

Рассмотрим следующие примеры:

  • Многооконный режим: вы просматриваете Элемент 1 в подробной панели, затем щелкаете Элемент 2 в списке. Подробная панель обновляется. Нажатие кнопки «Назад» вернет подробную панель к Элементу 1.
  • Однопанельный режим: происходит аналогичное изменение содержимого.

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

переход между двумя подробными панелями
PopUntilCurrentDestinationChange

При таком поведении стек "Назад" удаляется до тех пор, пока не изменится текущий пункт навигации . Это в равной степени относится как к однопанельным, так и к многопанельным макетам.

Рассмотрим следующие примеры:

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

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

навигация между подробным и списочным окнами
PopLatest

Эта опция удаляет из стека возврата только самый последний пункт назначения. Используйте эту опцию для возврата назад без пропуска промежуточных состояний.

После выполнения этих шагов ваш код должен выглядеть примерно так:

NavigableListDetailPaneScaffold(
    navigator = navigator,
    listPane = {
        AnimatedPane {
            ListContent(
                words = sampleWords,
                selectionState = navigator.currentDestination?.contentKey?.let {
                    SelectionVisibilityState.ShowSelection(it)
                } ?: SelectionVisibilityState.NoSelection,
                onWordClick = { word ->
                    scope.launch {
                        navigator.navigateTo(ListDetailPaneScaffoldRole.Detail, word)
                    }
                },
                animatedVisibilityScope = this@AnimatedPane,
                sharedTransitionScope = this@SharedTransitionLayout
            )
        }
    },
    detailPane = {
        AnimatedPane {
            DetailContent(
                definedWord = navigator.currentDestination?.contentKey,
                animatedVisibilityScope = this@AnimatedPane,
                sharedTransitionScope = this@SharedTransitionLayout,
                onClosePane = {
                    scope.launch {
                        navigator.navigateBack(
                            backNavigationBehavior = BackNavigationBehavior.PopUntilScaffoldValueChange
                        )

                    }
                }
            )
        }
    }