Jetpack之Navigation学习
程序员文章站
2022-05-28 19:40:58
...
一、什么是Navigation
Navigation是google推出的Jetpack架构组件里的一种,一个Activity内的多个Fragment由Navigation负责页面跳转并互相传值,同时能保留先前多个Activity的切换的用户体验。
二、Navigation有啥优点
- 传统的一个页面就是一个Activity,Activity是重量级的,一个Activity的创建是很复杂的,会销毁很多内存资源,Fragment就显得比较轻巧
- 能完美的保留多个Activity跳转的效果,能轻松的实现页面间的传值
- 大量的Activity被Fragment替换,生命周期的维护变得简单,同时尽可能的避免了内存泄漏
- Navigation可以直接在xml文件里配置导航路由,能直观的看到多个页面的跳转流程
三、开始使用
1.添加依赖
dependencies {
def nav_version = "2.3.1"
// Java language implementation
implementation "androidx.navigation:navigation-fragment:$nav_version"
implementation "androidx.navigation:navigation-ui:$nav_version"
// Kotlin
implementation "androidx.navigation:navigation-fragment-ktx:$nav_version"
implementation "androidx.navigation:navigation-ui-ktx:$nav_version"
}
2.创建导航配置文件
- 创建一个Activity和两个Fragment
- 在res目录下新建navigation目录,并在改目录下创建xml配置文件,随意命名一下my_nav.xml
- 打开my_nav.xml,并点击desgin进入到设计页面,点击+号可以添加需要跳转的页面
- 创建了多个页面之后,点击每个页面右边的小圆点然后拖到跳转的目标页面上,就实现了流程图样式
- 切换到code模式,xml文件里有一些配置语句
开始的页面,就是打开Acticity首次加载的是哪个Fragemnt
app:startDestination
<fragment
android:id="@+id/myFragment1"
android:name="com.yckj.ui.fragment.Fragment1"
android:label="fragment_blank"
//Fragment1对应的自己的xml布局文件
tools:layout="@layout/fragment_fragment1">
<action
//为当前的跳转action设置id,后面页面跳转的时候需要用到
android:id="@+id/action_blankFragment_to_blankFragment2"
//Fragment1跳转到哪个页面上
app:destination="@id/myFragment2"
//入场返场动画
app:enterAnim="@anim/h_fragment_enter"
app:exitAnim="@anim/h_fragment_exit"
app:popEnterAnim="@anim/h_fragment_pop_enter"
app:popExitAnim="@anim/h_fragment_pop_exit" />
</fragment>
h_fragment_enter.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="150">
<translate
android:fromXDelta="10%p"
android:interpolator="@android:anim/decelerate_interpolator"
android:toXDelta="0" />
<alpha
android:fromAlpha="0"
android:toAlpha="1.0" />
</set>
h_fragment_exit.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="200">
<translate
android:fromXDelta="0"
android:interpolator="@android:anim/accelerate_interpolator"
android:toXDelta="-10%p" />
</set>
h_fragment_pop_enter.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="200">
<translate
android:fromXDelta="-10%p"
android:toXDelta="0" />
</set>
h_fragment_pop_exit.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="200">
<translate
android:fromXDelta="0"
android:toXDelta="10%p" />
<alpha
android:fromAlpha="1.0"
android:toAlpha="0" />
</set>
- 配置Activity,将Activity和导航配置文件联系起来
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/white"
android:orientation="vertical">
<fragment
//设置为true表明会拦截返回键的操作
app:defaultNavHost="true"
//这里声明了用的是哪个导航配置文件
app:navGraph="@navigation/my_nav"
android:id="@+id/nav_host_fragment"
//固定不变的
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent">
</fragment>
</LinearLayout>
四、页面之间的跳转与传值
//页面的跳转:两个方式都是一样的效果,用哪个都可以
//方式一
//这个view可以用onclick回调里的view
Navigation.findNavController(view).
//navigate里的id是导航配置文件action节点上的id
navigate(R.id.action_blankFragment_to_blankFragment2);
//方式二
//findNavController传入当前的fragment
NavHostFragment.findNavController(Fragment1.this).
//navigate参数同上
navigate(R.id.action_blankFragment_to_blankFragment2);
以上的方式是不传参的情况下,如果传参的话,navigate方法里是可以传Bundle的
第二个页面取值还是正常的fragment取值就行(getArguments())
public void navigate(@IdRes int resId, @Nullable Bundle args)
//两种方法都可以关闭当前页 返回上一页
Navigation.findNavController(v).navigateUp();
NavHostFragment.findNavController(Fragment3.this).navigateUp()