preface
In mobile development, different people have different capabilities for developers. Just like reading a book, there are a thousand Hamlets for a thousand readers. But anyway, if you’re a software developer you have to learn how an operating system like Windows or Linux works. Let’s cut to the chase and get straight to it. Due to the longer length of the article, notice in advance: at the end of the article there is a large number of handwritten framework source code and framework thinking data, need to directly skip to the end of the article to get]
In actual combat
Before we do that, let’s take a look at the three key elements in Navigation. They are:
- Navigation Graph (New XML Resource) As shown in our first diagram, this is a New resource file where the user can visually see the Destination he can reach (the screen interface the user can reach) and the process relationships.
- NavHostFragment (Layou XML View) Container for the current Fragment
- NavController (Kotlin/Javaobject) Controller of navigation
Maybe this is a little abstract, but to use a less appropriate metaphor, we can think of the Navigation Graph as a map, the NavHostFragment as a car, and the NavController as a steering wheel in the car, The Navigation Graph shows you the Destination and the path to each Destination. The NavHostFragment can go to any Destination on the map, but it’s the steering wheel NavController that decides where to go. Although it depends on the driver (user).
The first step is to add dependencies
The build.gradle file for the module layer needs to be added:
Ext. NavigationVersion = "2.0.0" dependencies {//... implementation "androidx.navigation:navigation-fragment- ktx:$rootProject.navigationVersion" implementation "androidx.navigation:navigation-ui-ktx:$rootProject.navigationVersion" }Copy the code
If you want to use the SafeArgs plugin, add it to the build.gradle file in your project directory:
Buildscript {ext navigationVersion = "2.0.0 dependencies {classpath androidx. Navigation: navigation - safe - the args - gradle - plugin:$navigationVersion" } }Copy the code
And the build.gradle file below the module is added:
apply plugin: 'kotlin-android-extensions'
apply plugin: 'androidx.navigation.safeargs'
Copy the code
Step 2 Create a navigation
- Create a navigation directory under the res directory -> right-click navigation directory and create a New navigation resource file
- To create a
Destination
Copy the code
If the
navigation
Copy the code
It’s our navigation tool,
Destination
Copy the code
It’s our destination. I’ve already written one down before
WelcomeFragment
Copy the code
,
LoginFragment
Copy the code
and
RegisterFragment
Copy the code
To add
Destination
Copy the code
After the operation is completed, it is shown as follows:
Add the Destination
In addition to the visual interface, it is still necessary to look at the composition of the content, login_navigation.xml:
<navigation ... android:id="@+id/login_navigation" app:startDestination="@id/welcome"> <fragment android:id="@+id/login" android:name="com.joe.jetpackdemo.ui.fragment.login.LoginFragment" android:label="LoginFragment" tools:layout="@layout/fragment_login" /> <fragment android:id="@+id/welcome" android:name="com.joe.jetpackdemo.ui.fragment.login.WelcomeFragment" android:label="LoginFragment" tools:layout="@layout/fragment_welcome"> <action ... /> <action ... /> </fragment> <fragment android:id="@+id/register" android:name="com.joe.jetpackdemo.ui.fragment.login.RegisterFragment" android:label="LoginFragment" tools:layout="@layout/fragment_register" > <argument ... /> </fragment> </navigation>Copy the code
I’ve omitted some unnecessary code here. Let’s look at the attributes of the Navigation tag:
App :startDestination Default starting location
The third step is to create NavHostFragment
We create a new LoginActivity in the activity_login.xml file:
<androidx.constraintlayout.widget.ConstraintLayout ... > <fragment android:id="@+id/my_nav_host_fragment" android:name="androidx.navigation.fragment.NavHostFragment" app:navGraph="@navigation/login_navigation" app:defaultNavHost="true" android:layout_width="match_parent" android:layout_height="match_parent"/> </androidx.constraintlayout.widget.ConstraintLayout>Copy the code
A few attributes need to be explained:
- The android: name value must be androidx. Navigation. Fragments. NavHostFragment, this is a NavHostFragment declaration
- App :navGraph stores the resource file that is used in the second step to set up the Navigation Graph
- App :defaultNavHost=”true” is associated with the system’s return button
Step 4: Interface jump, parameter transfer and animation
On the WelcomeFragment, click the Login and Register buttons to jump to the LoginFragment and RegisterFragment, respectively.
WelcomeFragment. Here I implement the WelcomeFragment in two ways:
Method one uses ID navigation
Target: WelcomeFragment indicates the WelcomeFragment that displays the data whose key is name to the LoginFragment. Have a account ? The click events of the Login button are as follows:
BtnLogin. SetOnClickListener {/ / set the animation parameter val navOption = navOptions {anim {enter = state Richard armitage nim. Slide_in_right exit = Slide_in_left popExit = r.lem.slide_out_right}} val bundle = bundle () bundle.putString("name","TeaOf") findNavController().navigate(R.id.login, bundle,navOption) }Copy the code
The following LoginFragment receiving code is relatively simple. You can directly obtain the Bundle in the Fragment. The final result:
LoginFragment
Method two uses Safe Args **
Target: WelcomeFragment Sends data to the RegisterFragment through Safe Args. The RegisterFragment displays data after receiving the data. Take a look at the login_navigation.xml already shown:
<navigation ... > <fragment ... /> <fragment android:id="@+id/welcome" > <action android:id="@+id/action_welcome_to_login" app:destination="@id/login"/> <action android:id="@+id/action_welcome_to_register" app:enterAnim="@anim/slide_in_right" app:exitAnim="@anim/slide_out_left" app:popEnterAnim="@anim/slide_in_left" app:popExitAnim="@anim/slide_out_right" app:destination="@id/register"/> </fragment> <fragment android:id="@+id/register" ... > <argument android:name="EMAIL" android:defaultValue="[email protected]" app:argType="string"/> </fragment> </navigation>Copy the code
You may have noticed the action and argument tags in the login_navigation.xml resource file in the navigation directory.
- App :destination Indicates the Id of the fragment arrived after the hop is complete
- App :popUpTo Popup the fragment from the stack to a fragment with an Id
Argument label
- Android :name Tag name
- App :argType Indicates the type of the tag
- Android: defaultValue default values
By clicking the Make Project button in Android Studio, you can see that the system has generated two classes for us:
System generated classes
WelcomeFragment
Copy the code
In the
JOIN US
Copy the code
Button click event:
btnRegister.setOnClickListener {
val action = WelcomeFragmentDirections
.actionWelcomeToRegister()
.setEMAIL("[email protected]")
findNavController().navigate(action)
}
Copy the code
Receive in RegisterFragment:
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
// ...
val safeArgs:RegisterFragmentArgs by navArgs()
val email = safeArgs.email
mEmailEt.setText(email)
}
Copy the code
And the effect:
RegisterFragment needs to be mentioned if not
Safe Args
Copy the code
.
action
Copy the code
Can be caused by
Navigation.createNavigateOnClickListener(R.id.next_action, null)
Copy the code
Mode generation, interested can write their own.
More and more
Navigation can be bound with menus, drawers, and bottom Navigation, for example, bottom Navigation. I created main_navigation.xml in the navigation directory, MainActivity, and activity_main.xml:
<LinearLayout ... > <fragment android:id="@+id/my_nav_host_fragment" android:name="androidx.navigation.fragment.NavHostFragment" android:layout_width="match_parent" app:navGraph="@navigation/main_navigation" app:defaultNavHost="true" android:layout_height="0dp" android:layout_weight="1"/> <com.google.android.material.bottomnavigation.BottomNavigationView android:id="@+id/navigation_view" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@android:color/white" app:itemIconTint="@color/colorAccent" app:itemTextColor="@color/colorPrimary" app:menu="@menu/menu_main"/> </LinearLayout>Copy the code
Processing in MainActivity is also quite simple:
class MainActivity : AppCompatActivity() {
lateinit var bottomNavigationView: BottomNavigationView
override fun onCreate(savedInstanceState: Bundle?) {
//...
val host: NavHostFragment =
supportFragmentManager.findFragmentById(R.id.my_nav_host_fragment) as NavHostFragment
val navController = host.navController
initWidget()
initBottomNavigationView(bottomNavigationView,navController)
}
private fun initBottomNavigationView(bottomNavigationView: BottomNavigationView, navController: NavController) {
bottomNavigationView.setupWithNavController(navController)
}
private fun initWidget() {
bottomNavigationView = findViewById(R.id.navigation_view)
}
}
Copy the code
Effect: