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:
-
Build MainActivity: Do controls
- Outside of onCreate: Declare BottomNavigationView in the layout
- Inside onCreate: Instantiate BottomNavigationView in the layout
- Get navHostFragment
- Get navController
- Bind BottomNavigationView to navController
-
Build activity_main. XML
-
Write FragmentContainerView
- id
- Name: NavHostFragment
- DefaultNavHost =”true”
- Specify navGraph=”@navigation/nav_graph_main”
-
Write BottomNavigationView
- The built-in menu
-
Write menu: improve item details
- id
- icon
- title
-
-
Write a navigation chart:
-
New navigation package: RES /navigation
-
Create a new navigation diagram file: nav_graph_main
-
Fill the navigation diagram with a Fragment tag: what is really used to display the interface
-
Complete fragment tag details:
-
Specify ID: as the forward address
android:id="@+id/page1Fragment" Copy the code
-
Specify name: reflection execution
android:name="com.derry.navigation.MainPage1Fragment" Copy the code
-
Specify the label: fragment label
-
Specify layout: Fragment layout file
-
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:
- 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).
-
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:
-
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
-
-
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:
-
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
-
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
-
-
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
-
Gets the bottom navigation bar instance
bottomNavigationView = findViewById(R.id.nav_view) Copy the code
-
Need to get the fragment
public FragmentManager getSupportFragmentManager() { return mFragments.getSupportFragmentManager(); } Copy the code
-
Get the main navigation page according to the ID
findFragmentById(R.id.my_nav_host_fragment) Copy the code
-
In this case, the fragment needs to be strongly converted into a fragment
as NavHostFragment Copy the code
-
There is a possibility of strong transfer failure, so add? On failure, it is set to null
as NavHostFragment? Copy the code
-
Get the controller of navigation
val controller = navHostFragment!! .navControllerCopy the code
-
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
-
-