Навигация складного устройства
Компонент навигации складного устройства — это библиотека, созданная по принципу компонента навигации Android. Он помогает разработчикам реализовать навигацию фрагментов в различных режимах экрана или адаптировать существующее приложение к шаблону навигации складного устройства;
Компонент навигации складного устройства состоит из трех ключевых частей:
- Граф навигации. XML-ресурс, который содержит все сведения о навигации в одном централизованном расположении. Он такой же, как и граф из компонента навигации, предоставляемого Google.
- FoldableNavHost. Пустой контейнер, отображающий пункты назначения из графа навигации. Реализация для навигации складного устройства —
FoldableNavHostFragment
. - FoldableNavController. Объект, управляющий навигацией приложения в
FoldableNavHost
.
Обзор
Приложения на складных устройствах и устройствах с двумя экранами могут отображаться на одном экране или быть распределены через компонент свертывания. При запуске приложения:
- На устройстве с одним экраном будет виден только один фрагмент (A).
- Если приложение преобразовано для просмотра через компонент свертывания, первый фрагмент (A) будет находиться на одной стороне свертывания, а другая останется пустой.
Если в первоначальном состоянии перейти к другому фрагменту (B), новый фрагмент будет открыт на конечном экране.
Если пользователь переходит к третьему фрагменту (C), он будет показан на конечном экране, а предыдущий фрагмент (B) будет перемещен на начальный экран.
- При перемещении приложения на один экран все фрагменты с конечного экрана переходят на начальный, а фрагмент (C) располагается поверх остальных окон.
- Когда приложение с положения на одном экране растягивается через свертывание или петлю, а навигационная стопка содержит более двух фрагментов, последний из них будет перемещен на конечный экран.
Изменение назначения области экрана для действий
Вы можете указать, где будет отображаться новый фрагмент, с помощью атрибута launchScreen
в графе навигации.
Возможные значения параметра launchScreen
:
start
— фрагмент будет открыт на первом экранеend
— фрагмент будет открыт на втором экранеboth
— фрагмент будет охватывать всю отображаемую область
В этом примере навигации XML показано, как использовать этот атрибут:
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/home"
app:startDestination="@+id/titleScreen">
<fragment
android:id="@+id/titleScreen"
android:name="com.microsoft.device.dualscreen.navigation.sample.homescreen.TitleFragment"
android:label="@string/title_home"
tools:layout="@layout/fragment_title">
<action
android:id="@+id/action_title_to_about"
app:launchScreen="end"
app:destination="@id/aboutScreen"
app:enterAnim="@anim/slide_in_right"
app:exitAnim="@anim/slide_out_left"
app:popEnterAnim="@anim/slide_in_right"
app:popExitAnim="@anim/slide_out_left" />
</fragment>
</navigation>
Важно!
Этот атрибут можно изменить, только непосредственно изменив XML-файл. Его нельзя изменить с помощью редактора Android Studio.
Образец
Вы можете скачать пример приложения для навигации, чтобы ознакомиться со всеми этими поведениями.
Импорт библиотеки в проект
Добавьте зависимость в файл уровня модуля build.gradle:
Если проект создан с использованием Java, необходимо добавить зависимость kotlin-stdlib в файл build.gradle на уровне модуля. (Это связано с тем, что некоторая часть библиотеки была создана с помощью Kotlin.)
dependencies { implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" }
Эти компоненты созданы по принципу компонента навигации, предоставляемого Google, поэтому в библиотеке навигации складного устройства содержится зависимость для него.
Создание графа навигации
Граф навигации — это XML-файл ресурсов со всеми путями навигации вашего приложения с использованием назначений и действий. Граф навигации можно создать с помощью редактора навигации Android Studio или вручную через редактор XML. Дополнительные сведения можно найти в статье о создании графа навигации.
Добавление NavHost к действию
Компонент навигации складного устройства предназначен для приложений с одним основным действием и несколькими назначениями фрагментов. Главное действие связано с графом навигации и будет содержать объект FoldableNavHostFragment
, отвечающий за смену назначений фрагментов. Если в вашем приложении будет несколько действий, каждое из них будет иметь собственный граф навигации.
Это пример основного XML-файла макета действия, в котором показано, как задать атрибут app:navGraph
:
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/surface_duo_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.fragment.app.FragmentContainerView
android:id="@+id/nav_host_fragment"
android:name="androidx.navigation.FoldableNavHostFragment"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:navGraph="@navigation/nav_graph" />
</androidx.constraintlayout.widget.ConstraintLayout>
FoldableNavHost
можно также задать программно:
val navHostFragment = FoldableNavHostFragment.create(navGraphId)
fragmentManager.beginTransaction()
.add(containerId, navHostFragment, fragmentTag)
.commitNow()
Дополнительные сведения о добавлении FoldableNavHost
см. в статье о добавлении NavHost к действию.
Переход в назначение
Этот фрагмент кода можно использовать для перехода фрагментов в соответствии с правилами навигации складного устройства:
class SomeFragment : Fragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
view.findViewById<Button>(R.id.btn_next).setOnClickListener {
findFoldableNavController().navigate(R.id.action_next)
}
}
}
Обновление компонентов пользовательского интерфейса с помощью FoldableNavigationUI
FoldableNavigationUI
— это аналогичный компонент, такой как NavigationUI
в компоненте навигации Jetpack, и он содержит статические методы, управляющие навигацией с помощью верхней панели приложения, панели навигации и нижней структуры навигации.
Вы можете найти дополнительные сведения о
FoldableNavigationUI
содержит следующие методы, аналогичные предоставленным NavigationUI
:
// same method name, with foldable parameter
boolean onNavDestinationSelected(MenuItem item, FoldableNavController navController)
boolean navigateUp(FoldableNavController navController, Openable openableLayout)
boolean navigateUp(FoldableNavController navController, FoldableAppBarConfiguration configuration)
// method name changed to reflect foldable navigation
void setupActionBarWithFoldableNavController(AppCompatActivity activity, FoldableNavController navController)
void setupActionBarWithFoldableNavController(AppCompatActivity activity, FoldableNavController navController, Openable openableLayout)
void setupActionBarWithFoldableNavController(AppCompatActivity activity, FoldableNavController navController, FoldableAppBarConfiguration configuration)
void setupWithFoldableNavController(Toolbar toolbar, FoldableNavController navController)
void setupWithFoldableNavController(Toolbar toolbar, FoldableNavController navController, Openable openableLayout)
void setupWithFoldableNavController(Toolbar toolbar, FoldableNavController navController, FoldableAppBarConfiguration configuration)
void setupWithFoldableNavController(CollapsingToolbarLayout collapsingToolbarLayout, Toolbar toolbar, FoldableNavController navController)
void setupWithFoldableNavController(CollapsingToolbarLayout collapsingToolbarLayout, Toolbar toolbar, FoldableNavController navController, Openable openableLayout)
void setupWithFoldableNavController(CollapsingToolbarLayout collapsingToolbarLayout, Toolbar toolbar, FoldableNavController navController, FoldableAppBarConfiguration configuration)
void setupWithFoldableNavController(NavigationView navigationView, FoldableNavController navController)
void setupWithFoldableNavController(BottomNavigationView bottomNavigationView, FoldableNavController navController)
Перенос существующих приложений в систему навигации складного устройства
Существующие приложения, использующие компонент навигации, предоставляемый Google, могут добавлять функции складного устройства, выполнив следующие действия:
Вместо
NavHostFragment
в представлении контейнера фрагментов используйтеFoldableNavHostFragment
, изменив<androidx.fragment.app.FragmentContainerView android:id="@+id/nav_host_fragment" android:name="androidx.navigation.NavHostFragment"
значение
<androidx.fragment.app.FragmentContainerView android:id="@+id/nav_host_fragment" android:name="androidx.navigation.FoldableNavHostFragment"
Используйте
findFoldableNavController
, чтобы получить экземпляр дляFoldableNavController
и воспользоваться им для перехода внутри графа навигации путем измененияfindNavController().navigate(R.id.action_next)
значение
findFoldableNavController().navigate(R.id.action_next)
Используйте
FoldableNavigationUI
вместоNavigationUI
путем измененияval navHostFragment = supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment val navController = navHostFragment.navController val appBarConfiguration = AppBarConfiguration(navController.graph) setupActionBarWithNavController(navController, appBarConfiguration)
значение
val navHostFragment = supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as FoldableNavHostFragment val navController = navHostFragment.navController val appBarConfiguration = FoldableAppBarConfiguration(navController.graph) setupActionBarWithFoldableNavController(navController, appBarConfiguration)