Android JetPack架构组件学习之Navigation
程序员文章站
2022-03-13 17:09:05
...
文章目录
Navigation
Navigation简介
导航架构组件简化了Android应用程序中导航的实现,通过在xml中添加元素并指定导航的起始和目的地,从而在Fragment之间建立连接,在Activity中调用xml中设置的导航action实现跳转界面到目的地。简单来说,它和之前在活动中调用startActivity的区别就类似于代码布局和xml中layout布局一样,既简单又可视化。
Navigation设置操作
在项目中设置Navigation
-
在项目中开启Navigation支持
-
添加组件依赖
def nav_version = "1.0.0-alpha06" implementation "android.arch.navigation:navigation-fragment:$nav_version" // use -ktx for Kotlin implementation "android.arch.navigation:navigation-ui:$nav_version" // use -ktx for Kotlin // optional - Test helpers androidTestImplementation "android.arch.navigation:navigation-testing:$nav_version" // use -ktx for Kotlin
Navigation编辑器
-
创建资源文件
在 res 目录右击,选择 New > Android Resource File,Resource type 选择 Navigation。 -
创建destination(目的地)
创建destination的方式分为两种
- 在Navigation编辑器中Create blank destination,如下图所示:
这种方式会在一级路径下创建Fragment。
- 外部创建后,在编辑器中引入
可引入Activity,Fragment等组件。
-
配置navigation
-
android:name
,指定Fragment路径; -
tools:layout
,指定布局文件; -
app:startDestination
,指定起始项。
<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_test" app:startDestination="@id/test1Fragment"> <fragment android:id="@+id/test1Fragment" android:name="com.sanmen.bluesky.jetpackdemo.Test1Fragment" android:label="fragment_test1" tools:layout="@layout/fragment_test1"> </fragment> ... </navigation>
-
在Activity中引用
-
第一种方式是在 xml 里写 fragment。如下:
<android.support.constraint.ConstraintLayout ...> ... <fragment android:layout_width="0dp" android:layout_height="0dp" android:id="@+id/fragment" android:name="androidx.navigation.fragment.NavHostFragment" app:navGraph="@navigation/nav_test" app:defaultNavHost="true" ...> </android.support.constraint.ConstraintLayout>
-
android:name
,指定 NavHostFragment,它实现了 NavHost,这是一个用于放置管理 destination 的空视图。 -
app:navGraph
,关联 NavHostFragment 和 nav_graph.xml 。 -
app:defaultNavHost
,指定 NavHostFragment 可以拦截处理返回键。
-
-
第二种方式是通过代码创建 NavHostFragment,修改 Activity 的 xml:
<?xml version="1.0" encoding="utf-8"?> <android.support.constraint.ConstraintLayout ... > <FrameLayout android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/frame_layout" /> </android.support.constraint.ConstraintLayout>
然后再Activity中引入:
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) val finalHost = NavHostFragment.create(R.navigation.nav_test) supportFragmentManager.beginTransaction() .replace(R.id.frame_layout, finalHost) .setPrimaryNavigationFragment(finalHost) // 等价于 xml 中的 app:defaultNavHost="true" .commit() }
Navigation连接
-
连接destination
一种方式,在编辑器可视界面中拖线连接。
另一种方式,在xml代码界面,为fragment添加。两种方式原理相同。 -
处理跳转
Navigation的跳转通过NavController对象来实现。获取方式如下:NavHostFragment.findNavController(Fragment)
Navigation.findNavController(Activity, @IdRes int viewId)
Navigation.findNavController(View)
调用 NavController 的
navigate
方法执行跳转,navigate 的参数可以是一个destination
(这里就是 fragment 在导航图 nav_graph 中的 id),也可以是action
的 id。override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) btnToBlank!!.setOnClickListener { //跳转方式1 Navigation.findNavController(getView()!!) .navigate(R.id.action_test1Fragment_to_blankFragment) } btnToPaging!!.setOnClickListener { //跳转方式2 NavHostFragment.findNavController(this) .navigate(R.id.action_test1Fragment_to_pagingActivity) } }
-
添加跳转动画
点击目标箭头(提示页面指向的箭头),并在属性面板中设置动画Transitions。
如图,在text1Fragment到blankFragment之间的跳转添加一个enter动画,在代码界面会发生如下改变(指定了当前Action的app:enterAnim属性):... <fragment android:id="@+id/test1Fragment" android:name="com.sanmen.bluesky.jetpackdemo.Test1Fragment" android:label="fragment_test1" tools:layout="@layout/fragment_test1"> <action android:id="@+id/action_test1Fragment_to_blankFragment" app:destination="@id/blankFragment" app:enterAnim="@anim/nav_default_enter_anim"/> ... </fragment>
-
传递数据
- 要跳转到BlankFragment,要往 BlankFragment里带数据,在目的 Fragment 里添加 < argument>
<navigation xmlns:android="http://schemas.android.com/apk/res/android" ... > <fragment android:id="@+id/blankFragment" android:name="com.sanmen.bluesky.jetpackdemo.BlankFragment" android:label="fragment_blank" tools:layout="@layout/fragment_blank"> <action android:id="@+id/action_blankFragment_to_liveDataActivity" app:destination="@id/liveDataActivity" app:enterAnim="@anim/nav_default_enter_anim"/> <argument android:name="value" android:defaultValue="defaultValue=1" /> </fragment> </navigation>
- Test1Fragment添加数据
... btnToBlank!!.setOnClickListener { //利用Bundle对象发送数据 val bundle = Bundle() bundle.putString("name","Blank") bundle.putInt("year",1210) //跳转方式1 Navigation.findNavController(getView()!!) .navigate(R.id.action_test1Fragment_to_blankFragment,bundle) } ...
- BlankFragment 获取数据
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,savedInstanceState: Bundle?): View? { ... //// 在接收的代码中,使用该 getArguments()方法检索包并使用其内容 arguments?.let {bundle -> var name = bundle.getString("name") var year = bundle.getInt("year") tvValue!!.text = "name:$name,year:$year" } ... }
- 要跳转到BlankFragment,要往 BlankFragment里带数据,在目的 Fragment 里添加 < argument>
问题记录
- fragment中默认创建的OnFragmentInteractionListener 接口用于处理Fragment之间的通信,基于共同的Activity为桥梁,并在Activity中实现OnFragmentInteractionListener 接口。
interface OnFragmentInteractionListener { // TODO: Update argument type and name fun onFragmentInteraction(uri: Uri) }
推荐阅读
-
Android项目实战(四十八):架构之组件化开发
-
Android学习笔记之——UI组件/RelativeLayout(相对布局)
-
Android ABC Jetpack学习之一文学会Navigation(附源码解析和使用封装)
-
Android开发之android架构学习和使用
-
Android Jetpack架构组件之Lifecycle
-
阿里巴巴内部Jetpack宝典意外流出!极致经典,堪称Android架构组件的天花板
-
Android学习笔记之——UI组件/LinearLayout(线性布局)
-
Android开发学习笔记——四大组件之ContentProvider
-
Android学习笔记之——UI组件/Button
-
Android Jetpack Navigation组件使用,跳转,传参,action,回退,动态加载等