Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Android JetPack: easy navigation with the new N...

Android JetPack: easy navigation with the new Navigation Controller

In the past few years implementing in-app navigation was always a pain. Google wants to change that and with this talk, we'll explore the new architecture component included in Android JetPack: The Navigation Controller.

Leonardo Pirro

October 06, 2018
Tweet

More Decks by Leonardo Pirro

Other Decks in Programming

Transcript

  1. The Navigation Problem • Android Framework never had a concise

    and real solution to manage a common problem like Navigation • Navigation is “hard” and there are a lot things that you have to solve by your own • A lot of boilerplate code = A LOT of bugs and crash
  2. Navigation Graph A navigation graph is a blueprint of possible

    navigation destinations and the actions that link them.
  3. Navigation Graph <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" app:startDestination="@id/signinFragment"> ... </navigation> •

    <navigation> is the root node of the navigation graph • <navigation> can contains one or more destination represented by <activity> or <fragment> • app:startDestination is an attribute which controls what destination is launched by default when the user first opens the app.
  4. Navigation Graph <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" app:startDestination="@id/signinFragment"> <fragment android:id="@+id/homeFragment" android:name=“com.lpirro.navigation.HomeFragment”

    tools:layout="@layout/fragment_home" /> </navigation> • android:id is the ID of the fragment that you can use to destination elsewhere in xml or code • android:name is your fragment class that will be instantiated when you navigate to that destination • tools:layout defines the layout xml file that should be shown in the graph editor
  5. The role of the Activity An entry-point to your app

    The activity manages any global navigation (BottomNavigation, NavigationDrawer, etc), but delegates to a NavHost for content
  6. The role of the Activity The activity manages any global

    navigation (BottomNavigation, NavigationDrawer, etc), but delegates to a NavHost for content
  7. The role of the Activity The activity manages any global

    navigation (BottomNavigation, NavigationDrawer, etc), but delegates to a NavHost for content
  8. Navigate to a destination val options = NavOptions.Builder() .setEnterAnim(R.anim.slide_in_right) .setExitAnim(R.anim.slide_out_left)

    .setPopEnterAnim(R.anim.slide_in_left) .setPopExitAnim(R.anim.slide_out_right) .build() buttonQuiz.setOnClickListener { view.findNavController().navigate(R.id.quizFragment, null, options) }
  9. <?xml version="1.0" encoding="utf-8"?> <android.support.constraint.ConstraintLayout ...> <android.support.v7.widget.Toolbar ... /> <fragment android:id="@+id/navHostHome"

    android:name=“androidx.navigation.fragment.NavHostFragment" ... /> <android.support.design.widget.BottomNavigationView android:id="@+id/bottomNavigationView" app:menu="@menu/bottom_navigation_main" /> </android.support.constraint.ConstraintLayout> res/layout/activity_main.xml
  10. <?xml version="1.0" encoding="utf-8"?> <android.support.constraint.ConstraintLayout ...> <android.support.v7.widget.Toolbar ... /> <fragment android:id="@+id/navHostHome"

    android:name=“androidx.navigation.fragment.NavHostFragment" ... /> <android.support.design.widget.BottomNavigationView android:id="@+id/bottomNavigationView" app:menu="@menu/bottom_navigation_main" /> </android.support.constraint.ConstraintLayout> res/layout/activity_main.xml
  11. <?xml version="1.0" encoding="utf-8"?> <android.support.constraint.ConstraintLayout ...> <android.support.v7.widget.Toolbar ... /> <fragment android:id="@+id/navHostHome"

    android:name=“androidx.navigation.fragment.NavHostFragment" ... /> <android.support.design.widget.BottomNavigationView android:id="@+id/bottomNavigationView" app:menu="@menu/bottom_navigation_main" /> </android.support.constraint.ConstraintLayout> Uses the same IDs of the destinations defined in the Navigation Graph res/layout/activity_main.xml KF
  12. <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" app:startDestination="@id/homeFragment"> <fragment android:id="@+id/quizFragment" android:name=“com.lpirro.navigationtalk.QuizFragment" android:label="Quiz" tools:layout="@layout/fragment_quiz"

    > </fragment> <fragment android:id="@+id/homeFragment" android:name=“com.lpirro.navigationtalk.HomeFragment" android:label="Home" /> <fragment android:id="@+id/filmFragment" android:name=“com.lpirro.navigationtalk.FilmFragment" android:label="Film" /> <fragment android:id="@+id/cinemaFragment" res/navigation/nav_graph.xml
  13. res/menu/bottomnav_menu.xml <menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto"> <item android:id="@+id/homeFragment" android:icon="@drawable/ic_nav_home" android:title="@string/nav_home" /> <item

    android:id="@+id/filmFragment" android:icon="@drawable/ic_nav_movies" android:title="@string/nav_movies" /> <item android:id="@+id/cinemaFragment" android:icon="@drawable/ic_nav_theatre" android:title="@string/nav_cinema" /> <item android:id="@+id/quizFragment" android:icon="@drawable/ic_nav_quiz" android:title="@string/nav_quiz"/> </menu>
  14. MainActivity.kt override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) setSupportActionBar(toolbar) val

    navController = Navigation.findNavController(this, R.id.navHost) NavigationUI.setupWithNavController(toolbar, navController) bottomNavigationView.setupWithNavController(navController) }
  15. Create an action <fragment android:id="@+id/homeFragment" android:name=“com.lpirro.app.home.HomeFragment" android:label="HomeFragment" > <action android:id="@+id/action_homeFragment_to_articleDetailFragment"

    app:destination="@id/articleDetailFragment" app:enterAnim="@anim/slide_in_right" app:exitAnim="@anim/slide_out_left" app:popEnterAnim=“@anim/slide_in_left" app:popExitAnim="@anim/slide_out_right" /> </fragment>
  16. MyFirebaseService.kt val bundle = Bundle() bundle.putParcelable("article", Article(id)) val deepLinkBuilder =

    NavDeepLinkBuilder(this) .setGraph(R.navigation.nav_graph) .setDestination(R.id.articleDetailFragment) .setArguments(bundle) val pendingIntent = deepLinkBuilder.createPendingIntent()