这里选用kotlin的项目,首先引入navigation和kotlin app/build.gradle如下
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: "androidx.navigation.safeargs.kotlin"
android {
...
dataBinding {
enabled true
}
compileOptions {
sourceCompatibility = '1.8'
targetCompatibility = '1.8'
}
kotlinOptions {
jvmTarget = JavaVersion.VERSION_1_8
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
//kotlin
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutinesVersion"
implementation 'androidx.core:core-ktx:1.2.0-alpha02'
implementation 'androidx.appcompat:appcompat:1.1.0-rc01'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
//navigation
implementation "androidx.navigation:navigation-fragment-ktx:$nav_dep"
implementation "androidx.navigation:navigation-ui-ktx:$nav_dep"
}
project/build.gradle
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
ext.kotlin_version = '1.3.41'
ext.nav_dep = '2.1.0-beta02'
ext.coroutinesVersion = '1.2.1'
repositories {
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.4.1'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath "androidx.navigation:navigation-safe-args-gradle-plugin:$nav_dep"
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
google()
jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
如果采用kotlin的话,项目中可能报错 Cannot inline bytecode built with JVM target 1.8 into bytecode that is being built with JVM target 。这时候只需在build的gradle中添加如下即可
compileOptions {
sourceCompatibility = '1.8'
targetCompatibility = '1.8'
}
kotlinOptions {
jvmTarget = JavaVersion.VERSION_1_8
}
现在的项目中只有一个默认创建的MainActivity以及XML,首先在res目录上右键new-AndroidResourceFile,在弹出的菜单中的ResourceType中选择navigation,然后填入fileName确定,然后在res/navigation目录下就会生成一个xml。它的内容如下
<?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" >
</navigation>
然后切换到Design模式中
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<fragment android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/my_nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
app:defaultNavHost="true"
app:navGraph="@navigation/nav_graph"
/>
</androidx.constraintlayout.widget.ConstraintLayout>
这里的defaultNavHost就是制定当前导航路径的主Fragment,而navGraph则是指定当前主fragment下所包含的所有导航信息。接下来看nav_graph这个文件的详细信息
<?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"
app:startDestination="@id/AFragment">
<fragment
android:id="@+id/AFragment"
android:name="com.example.jetpacknavigation.AFragment"
android:label="fragment_a"
tools:layout="@layout/fragment_a">
<action android:id="@+id/action_AFragment_to_BFragment"
app:destination="@id/BFragment"
/>
</fragment>
<fragment android:id="@+id/BFragment"
android:name="com.example.jetpacknavigation.BFragment"
android:label="fragment_b"
tools:layout="@layout/fragment_b">
</fragment>
</navigation>
这里面的action就是刚才添加箭头的作用,从自动生成的名字也可以看出就是从A到B的跳转。其中在根节点中的startDestination则为初始化默认显示的页面,而下面的action中的destination则是要到达的页面。那么如何 跳转呢,在AFragment中的按钮点击事件设置为
Navigation.findNavController(it).navigate(R.id.action_AFragment_to_BFragment)
就是拿到这个NavController然后调用它的navigate方法,参数则是上面定义的action的id,这样就可以实现跳转。很多时候跳转的时候需要携带参数,这时候我们可以通过如下方式传参
var bundle=Bundle()
bundle.putString("test","hello")
Navigation.findNavController(it).navigate(R.id.action_AFragment_to_BFragment,bundle)
在BFragment中通过getArguments.getString可以获取到传递过来的值。当然系统还为我们提供了一种简单的方法,直接在xml中生命参数
<fragment android:id="@+id/BFragment"
android:name="com.example.jetpacknavigation.BFragment"
android:label="fragment_b"
tools:layout="@layout/fragment_b">
<argument
android:name="taskId"
app:argType="string"/>
</fragment>
这里直接声明了该fragment需要一个String类型的参数,在A中调用Navigate方法如下
private val args:BFragmentArgs by navArgs()
这里的args就会解析到getArgument的值。不仅仅是传值,还可以设置动画,这里选中箭头,然后在右侧的Animation中选择相应的动画即可,这里有系统默认的,也可以在res/anim目录下建自己想要的动画