폴딩 가능한 탐색

접을 수 있는 탐색 구성 요소는 Android 탐색 구성 요소를 기반으로 빌드된 라이브러리입니다. 개발자는 다양한 화면 모드에 대한 조각 탐색을 구현하거나 기존 애플리케이션을 접을 수 있는 탐색 패턴에 맞게 조정할 수 있습니다.

접을 수 있는 탐색 구성 요소는 다음 세 가지 주요 부분으로 구성됩니다.

  • Navigation Graph - 하나의 중앙 위치에 모든 탐색 관련 정보를 포함하는 XML 리소스입니다. Google에서 제공하는 탐색 구성 요소의 것과 동일합니다.
  • FoldableNavHost - 탐색 그래프의 대상을 표시하는 빈 컨테이너입니다. 접을 수 있는 탐색에 대한 구현은 FoldableNavHostFragment입니다.
  • FoldableNavController - FoldableNavHost 내에서 앱 탐색을 관리하는 개체입니다.

개요

이중 화면 및 폴딩 가능한 디바이스의 애플리케이션은 단일 화면에 표시되거나 접기 기능에 걸쳐 있을 수 있습니다. 애플리케이션이 처음 시작되는 경우:

  • 단일 화면에서는 하나의 조각(A)만 표시됩니다.
  • 애플리케이션이 접기 기능을 통해 렌더링되는 경우 첫 번째 조각(A)은 접기의 첫 번째 면에 있고 접기의 다른 쪽은 비어 있습니다.

초기 상태에서 다른 조각(B)으로 이동하면 새 조각이 최종 화면에서 열립니다.

사용자가 세 번째 조각(C)으로 이동하면 최종 화면에 표시되며, 이전 조각(B)이 시작 화면에서 이동됩니다.

  • 앱이 단일 화면에 걸쳐 있는 것에서 이동하면 최종 화면의 모든 조각이 시작 화면으로 이동되고 (C)가 맨 위에 표시됩니다.
  • 앱이 단일 화면에서 접기 또는 힌지를 가로질러 확장되도록 이동되고 탐색 스택에 세 개 이상의 조각이 있는 경우 마지막 조각이 최종 화면으로 이동됩니다.

Six different dual-screen examples demonstrating how fragments A, B, and C would appear after different navigation steps

작업의 표시 영역 대상 변경

탐색 그래프의 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 편집기를 사용하여 수정할 수 없습니다.

샘플

탐색 샘플 앱을 다운로드하여 이러한 모든 동작을 확인할 수 있습니다.

라이브러리를 프로젝트로 가져오는 방법

  1. 종속성을 모듈 수준 build.gradle 파일에 추가합니다.

    dependencies {
       def nav_version = "1.0.0-alpha3"
       implementation "com.microsoft.device.dualscreen:navigation-fragment-ktx:$nav_version"
       implementation "com.microsoft.device.dualscreen:navigation-ui-ktx:$nav_version"
    }
    

  1. Java를 사용하여 프로젝트를 만드는 경우 kotlin-stdlib 종속성을 모듈 수준 build.gradle 파일에 추가해야 합니다. (이는 Kotlin을 이용하여 라이브러리의 일부를 만들었기 때문입니다.)

    dependencies {
       implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
    }
    

이러한 구성 요소는 Google에서 제공하는 탐색 구성 요소를 기반으로 빌드되므로 Foldable-Navigation 라이브러리에는 이에 대한 종속성이 포함되어 있습니다.

탐색 그래프 만들기

탐색 그래프는 대상 및 작업을 사용하여 앱의 모든 탐색 경로가 포함된 xml 리소스 파일입니다. 탐색 그래프는 Android Studio 탐색 편집기를 통해 만들거나 XML 편집기를 통해 수동으로 만들 수 있습니다. 탐색 그래프 만들기에서 자세한 정보를 찾을 수 있습니다.

활동에 NavHost 추가

접을 수 있는 탐색 구성 요소는 하나의 기본 작업 및 여러 조각 대상이 있는 앱용으로 설계되었습니다. 기본 작업은 탐색 그래프와 연결되며 조각 대상 교환을 담당하는 FoldableNavHostFragment를 포함합니다. 앱에 두 개 이상의 작업이 있는 경우 각 활동에는 고유한 탐색 그래프가 있습니다.

다음은 app:navGraph 특성을 설정하는 방법을 보여주는 기본 작업 XML 레이아웃 파일의 예입니다.

<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()

작업에 NavHost 추가에서 FoldableNavHost를 추가하는 방법에 대해 자세히 알아볼 수 있습니다.

이 코드 조각은 접을 수 있는 탐색 규칙에 따라 조각을 탐색하는 데 사용할 수 있습니다.

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를 통해 UI 구성 요소 업데이트

FoldableNavigationUI는 Jetpack 탐색 구성 요소의 NavigationUI와 유사한 구성 요소이며, 위쪽 앱 바, 탐색 서랍 및 아래쪽 탐색을 통해 탐색을 관리하는 정적 메서드를 포함합니다. 자세한 내용은 다음 페이지에서 확인할 수 있습니다.

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에서 제공하는 탐색 구성 요소를 사용하는 기존 애플리케이션은 다음 단계에 따라 접을 수 있는 기능을 추가할 수 있습니다.

  1. 다음을 변경하여 조각 컨테이너 뷰에서 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"
    
  2. findFoldableNavController를 사용하여 FoldableNavController에 대한 인스턴스를 가져오고 이를 사용해 변경하여 탐색 그래프 내부를 탐색합니다.

    findNavController().navigate(R.id.action_next)
    

    findFoldableNavController().navigate(R.id.action_next)
    
  3. 다음을 변경하여 NavigationUI 대신 FoldableNavigationUI를 사용합니다.

    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)