Basic use of Navigation

  • Summary:

    • There are almost 60 libraries in the JetPack component library

    • The initial intention of Navigation: Android should only have one Activity

      • An Activity acts as a control layer and has many fragments to display the page (contrast the front-end scaffolding).
  • Summary of Navigation.

    • It provides a consistent API for navigating between objects in Android applications, whether they are fragments, activities, or other components

    • No Navigation introduced:

      • TableLayout or Fragment is used for manual management
    • Main functions:

      • Navigate fragments, especially in a single Activity with multiple fragments
    • Project structure:

      • Overall schematic diagram

      • Details:

        • The overall use of a single MainActivity+ multiple fragments (with ViewModel), where the Activity only control, fragment display page

        • Nav_graph_main. XML: navigation diagram

          • Location: res/navigation
          • Function: specify the navigation fragments of information (id, name, label, layout, action)
        • Multiple fragment instances:

          • Displays the specific UI of the page
        • Fragmenti: fragmentiViewModel = 1:1

          • ViewModel(Maintain fragment data)
        • There is only one repository in the JetPack standard architecture model

Code implementation:

  • Implementation idea:

    1. Build MainActivity: Do controls

      1. Outside of onCreate: Declare BottomNavigationView in the layout
      2. Inside onCreate: Instantiate BottomNavigationView in the layout
      3. Get navHostFragment
      4. Get navController
      5. Bind BottomNavigationView to navController
    2. Build activity_main. XML

      1. Write FragmentContainerView

        1. id
        2. Name: NavHostFragment
        3. DefaultNavHost =”true”
        4. Specify navGraph=”@navigation/nav_graph_main”
      2. Write BottomNavigationView

        1. The built-in menu
      3. Write menu: improve item details

        1. id
        2. icon
        3. title
    3. Write a navigation chart:

      1. New navigation package: RES /navigation

      2. Create a new navigation diagram file: nav_graph_main

      3. Fill the navigation diagram with a Fragment tag: what is really used to display the interface

      4. Complete fragment tag details:

        1. Specify ID: as the forward address

           android:id="@+id/page1Fragment"
          Copy the code
        2. Specify name: reflection execution

           android:name="com.derry.navigation.MainPage1Fragment"
          Copy the code
        3. Specify the label: fragment label

        4. Specify layout: Fragment layout file

        5. New Action tag: Specify jump order (can be played with graphical interface)

           <action
               android:id="@+id/action_page2"
               app:destination="@id/page2Fragment" />
          Copy the code

Build MainActivity and Fragment

  • Engineering structure:

  • Code implementation:

    • MainPage1Fragment

      • Click on events: Jump to Fragment1

        Val BTN = view.findViewById<Button>(R.i.btn) btn.setOnClickListener {view -> Jump to the navigation chart Navigation.findNavController(view).navigate(R.id.action_page2) }Copy the code
    • MainPage2Fragment

      • Click on events: Jump to Fragment1, Fragment2

        Val BTN = view.findViewById<Button>(R.i.btn) btn.setOnClickListener {view -> // Jump to the page with the navigation diagram Navigation.findNavController(view).navigate(R.id.action_page1) // Navigation.findNavController(view).navigateUp(); } val btn2 = view.findViewById<Button>(r.i.btn2) btn2.setOnClickListener {view -> Navigation.findNavController(view).navigate(R.id.action_page3) }Copy the code
      • NavigateUp () : Rewind to the last fragment(the starting point of the last jump)

      • Navigate (R.i.D.action_page1) : specifies the ID for the jump

      • These two sentences have the same effect

    • MainPage3Fragment

      • Click on events: Jump to Fragment2

        BTN. SetOnClickListener {view - > Navigation. FindNavController (view). Navigate (da ction_page2 R.i) / / / / on the back step Navigation.findNavController(view).navigateUp(); }Copy the code
  • Build the navigation diagram of the navigation system: nav_gragh_main.xml

    • Original RES directory

    • Select res– > right click –>New– >Android Resource File

    • Type select Navigation(a new Navigation folder will be automatically created under the RES folder to store the newly created.xml)

    • The newly created RES resource directory

  • Create links between navigation diagrams and Fragments: Navigation diagrams find instances and instances are created before navigation diagrams

    • Click nav_graph_main. XML under RES /navigation and click on the Design option on the right side of the screen (switch to the following view)

      • Details:

        1. After clicking the red button in the image above, you can select the Fragment instance from the drop-down list and the first selected instance will be the default launch page of the navigation diagram (i.e. the one with the small house in the top corner).
        1. Change the default startup page of the navigation diagram: In the Design view, the default startup page has a small house in the upper left corner

          Modify nav_graph_main. XML: app:startDestination=”@id/page1Fragment

          The < navigation... < --! App :startDestination="@id/page1Fragment">Copy the code
    • Create jump relationships between fragments by dragging (specify action)

      • Effect:

      • Implementation details:

        1. How to establish a jump relationship between views?

          • Hover the mouse to the right of the jump starting point page, a blue circle appears, click (pull out a line), connect it to the target page of this jump

          • Redirect from page1Fragment to page2Fragment

            The < fragment... > <! <action android:id=" @id/ action_page2" app:destination="@id/page2Fragment" /> </fragment>Copy the code
        2. Why is the name attribute in a single fragment layout file the full class name of this fragment?

          • In order to activate by reflex

             <fragment
                      android:id="@+id/page1Fragment"
                      android:name="com.wasbry.navigation.MainPage1Fragment"
                      android:label="fragment_page1"
                      tools:layout="@layout/fragment_main_page1">
             ​
             </fragment>
            Copy the code
    • Nav_graph_main.xml

      <? The XML version = "1.0" encoding = "utf-8"? > <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/nav_graph_main.xml" app:startDestination="@id/page1Fragment"> <! < Fragment android:id="@+id/page1Fragment" android:id="@+id/page1Fragment" The android: name = "com. Derry. Navigation. MainPage1Fragment" reflection instantiation android: label = "fragment_page1" tools:layout="@layout/fragment_main_page1"> <! <action android:id=" @id/ action_page2" app:destination="@id/page2Fragment" /> </fragment> <! < Fragment android:id="@+id/page2Fragment" android:name="com.derry.navigation.MainPage2Fragment" android:label="fragment_page2" tools:layout="@layout/fragment_main_page2"> <action android:id="@+id/action_page1" app:destination="@id/page1Fragment" /> <action android:id="@+id/action_page3" app:destination="@id/page3Fragment" /> </fragment> <! -- TODO this is the third Fragment --> <! -- <navigation--> <! -- android:id="@+id/nav_graph_page3"--> <! -- app:startDestination="@id/page3Fragment">--> <fragment android:id="@+id/page3Fragment" android:name="com.derry.navigation.MainPage3Fragment" android:label="fragment_page3" tools:layout="@layout/fragment_main_page3"> <action android:id="@+id/action_page2" app:destination="@id/page2Fragment" /> </fragment> </navigation>Copy the code
      • Details:

        • The navigation diagram (nav_graph_main.xml), which is just XML, cannot deactivate three fragment instances;
        • You need to introduce this navigation diagram into your Activity layout and direct the navigation diagram in your Activity
  • Write the Activity layout file: Control the Fragment navigation diagram (this navigation diagram is very popular)

    • The introduction of fragments

         <androidx.fragment.app.FragmentContainerView
               android:id="@+id/my_nav_host_fragment"
               android:layout_width="match_parent"
               android:layout_height="wrap_content"
               android:layout_weight="9"
               android:name="androidx.navigation.fragment.NavHostFragment"
               app:defaultNavHost="true"
               app:navGraph="@navigation/nav_graph_main"/>
      Copy the code
      • Can be external label androidx. Fragments. App. FragmentContainerView replaced with fragments: function will reduce a lot of, this is secondary
      • NavHostFragment: This is the main fragment, introduced in the Activity layout file and pointing to the navigation diagram. This is the main fragment
      • App :defaultNavHost: Intercepts the system return key to activate the fragment’s task stack
      • App :navGraph: Activate the navigation graph in activity_main.xml
  • Implementation function: imitate wechat, click the bottom navigation bar to jump to the page

    • Implementation idea:

      1. Add a menu in activity_main.xml

         <com.google.android.material.bottomnavigation.BottomNavigationView
                 android:id="@+id/nav_view"
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
                 app:itemTextColor="#ff0000"
                 app:menu="@menu/menu" />
        Copy the code
      2. Introducing menu layout

        • Menu storage location:

        • Effect:

        • Code implementation:

          <? The XML version = "1.0" encoding = "utf-8"? > <menu xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@+id/page1Fragment" <item Android :id="@+id/page2Fragment" android:icon="@drawable/ic_launcher_foreground" Android :id="@+id/page2Fragment" /> <item Android :id="@+id/page2Fragment" <item Android :id="@+id/page3Fragment" android:icon="@drawable/ic_launcher_foreground" Android :id="@+id/page3Fragment" /> <item Android :id="@+id/page3Fragment" Android :icon="@drawable/ic_launcher_foreground" Android :title=" 3r "/> </menu>Copy the code
      1. Bind navigation to MainActivity

        • Code display:

           val navHostFragment =
               supportFragmentManager.findFragmentById(R.id.my_nav_host_fragment) as NavHostFragment?
          Copy the code
        • Implementation details: from Google official website code

          1. Gets the bottom navigation bar instance

             bottomNavigationView = findViewById(R.id.nav_view)
            Copy the code
          1. Need to get the fragment

             public FragmentManager getSupportFragmentManager() {
                 return mFragments.getSupportFragmentManager();
             }
            Copy the code
          2. Get the main navigation page according to the ID

             findFragmentById(R.id.my_nav_host_fragment)
            Copy the code
          3. In this case, the fragment needs to be strongly converted into a fragment

             as NavHostFragment
            Copy the code
          4. There is a possibility of strong transfer failure, so add? On failure, it is set to null

             as NavHostFragment?
            Copy the code
          5. Get the controller of navigation

            val controller = navHostFragment!! .navControllerCopy the code
          6. Get to the UI: Thanks to this sentence, the bottom navigation bar is clickable

            NavigationUI.setupWithNavController(bottomNavigationView!! , controller)Copy the code
      • Implementation effect

  • Modify MainActivity details:

    • Alias problem: Action also has its own ID, and the page it contains has a separate ID; You can call the action id to get the specified Page ID (destination), and then jump to the specified Page

    • Redirects the page to destination based on the ID

      • MainFragment1

         val btn = view.findViewById<Button>(R.id.btn)
         btn.setOnClickListener { view ->
             Navigation.findNavController(view).navigate(R.id.action_page2)
         }
        Copy the code
      • MainFragment2: There is a bounce mechanism (pressing the back key will call up by default)(can also be played by specifying an ID)

        val btn = view.findViewById<Button>(R.id.btn) btn.setOnClickListener { view -> Navigation.findNavController(view).navigate(R.id.action_page1) // Navigation.findNavController(view).navigateUp(); } val btn2 = view.findViewById<Button>(r.i.btn2) btn2.setOnClickListener {view -> Navigation.findNavController(view).navigate(R.id.action_page3) }Copy the code
      • MainFragment3

        val btn = view.findViewById<Button>(R.id.btn) btn.setOnClickListener { view -> Navigation. FindNavController (view). Navigate (da ction_page2 R.i) / / / / on the back step Navigation.findNavController(view).navigateUp(); }Copy the code
  • You can actually select ButtomNavigationActivity when you create a new project

    • Schematic diagram:

    • Project structure:

      • SRC has three packages, each corresponding to a fragment+ViewModel

      • Res /layout: layout files with corresponding fragments

      • Res/Navigation: has the corresponding navigation chart

      • Res /menu: indicates a corresponding menu

    • Use this method and write their own similarities:

      • Project architecture and implementation ideas are basically consistent
      • Navhostfragments have also been introduced in activity_main.xml
    • Differences between using this method and writing yourself:

      • It is not wired inside, using fragments to play directly

      • This one is more professional:

        • The ViewModel cooperate LiveData (MutableLiveData)
        • More standardized layering
    • Problems with using this method

      • Components encounter many problems in higher versions:

        • Change the SDK version to 30

        • 31 is problematic on both Windows and MAC

      • Modify the registry file: Modify the Activity whose built-in label is BootomNavigationActivity

        • Add the attribute modification exported