前言
JetPack是Google在2018年推出的一套组件、工具和指导 ,用于方便开发者更加方便的开发Android程序。
Navigation是JetPack中的一个导航组件,个人理解主要目的是用来处理页面之间的导航跳转切换,处理Activity、Fragment、Dialog之间的跳转与切换,不过大家主要是用来做Fragment之间的堆栈管理,本系列以这个为开端:
1、Fragment的创建
2、Fragment的切换
3、Fragment的堆栈管理
4、Fragment之间的参数传递
5、Activity与Fragment的参数传递(Fragment跳转到Activity的参数传递暂时没了解是不是有独特的传值方式)
6、Android Studio对Navigation的面板支持
对于Navigation官方开发了kotlin的相关插件和依赖库进行支持,所以本文使用kotlin进行编码演示。
本文主要是基于官方demo及其官方文档并进行个人的修正理解进行编写。
参考链接:
1、https://developer.android.google.cn/guide/navigation
2、https://codelabs.developers.google.com/codelabs/android-navigation/index.html?index=…%2F…index#3
Fragment的创建
1、先创建一个Activity和三个Fragment以及配套的布局文件
这里需要添加两个依赖:
implementation "androidx.navigation:navigation-fragment-ktx:2.1.0"
implementation "androidx.navigation:navigation-ui-ktx:2.1.0"
MainActivity.kt
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
}
activity_main.xml
<?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:id="@+id/root"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<fragment
android:id="@+id/nav_host_fragment"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
MainPage1Fragment.kt
class MainPage1Fragment : Fragment() {
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View {
return inflater.inflate(R.layout.fragment_item1, container, false)
}
}
MainPage2Fragment.kt
class MainPage2Fragment : Fragment() {
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View {
return inflater.inflate(R.layout.fragment_item2, container, false)
}
}
MainPage3Fragment.kt
class MainPage3Fragment : Fragment() {
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View {
return inflater.inflate(R.layout.fragment_item3, container, false)
}
}
fragment_item1.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/go"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="我是第一个页面,去第二个Fragment"/>
</LinearLayout>
fragment_item2.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/go"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="我是第二个页面,去第三个Fragment"/>
</LinearLayout>
fragment_item3.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/item_fragment3">
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/go"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="我是第三个页面,去第一个Fragment"/>
</LinearLayout>
使用Navigation展示Fragment
这里需要添加两个依赖:
implementation "androidx.navigation:navigation-fragment-ktx:2.1.0"
implementation "androidx.navigation:navigation-ui-ktx:2.1.0"
创建navigation文件
右键New -> Android Resource File,选择Resource Type的类型为Navigation,并为该文件定义文件名字后创建该文件,具体如下:
创建成功后布局如下:
在该页面填充以下代码:
<?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/test_nav"
app:startDestination="@id/mainPage1Fragment">
<fragment
android:id="@+id/mainPage1Fragment"
android:name="com.example.test.fragment.MainPage1Fragment"
android:label="MainPage1Fragment"
tools:layout="@layout/fragment_item1">
</fragment>
<fragment
android:id="@+id/mainPage2Fragment"
android:name="com.example.test.fragment.MainPage2Fragment"
android:label="MainPage2Fragment"
tools:layout="@layout/fragment_item2">
</fragment>
<fragment
android:id="@+id/mainPage3Fragment"
android:name="com.example.test.fragment.MainPage3Fragment"
android:label="MainPage3Fragment"
tools:layout="@layout/fragment_item3">
</fragment>
</navigation>
注意:
<navigation>
是每个导航图的根节点。<navigation>
包含一个或多个以或表示的目的地。app:startDestination
是一个属性,它指定用户首次打开应用程序时默认启动的目的地。android:id
为该片段定义一个ID,您可以使用该ID引用此XML和代码中其他位置的目标。android:name
声明当您导航到该目的地时要实例化的片段的全限定类名称。tools:layout
指定应在图形编辑器中显示的布局。
也可以通过Design面板进行添加Fragment:
修改activity_main.xml
将activity_main.xml与新创建的navigation进行关联
<fragment
android:id="@+id/nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="true"
app:navGraph="@navigation/test_nav" />
根据官方示例也可以将<fragment></fragment>
修改为<androidx.fragment.app.FragmentContainerView></androidx.fragment.app.FragmentContainerView>
注意:
android:name="androidx.navigation.fragment.NavHostFragment"
和app:defaultNavHost="true"
连接系统恢复按钮app:defaultNavHost="true"
app:navGraph="@navigation/mobile_navigation"
将关联到NavHostFragment
导航图。该导航图在此指定了用户可以导航到的所有目的地NavHostFragment
。
至此:使用Navigation创建了一个可以展示的Fragment。
参考链接
-
Kotlin中的基础知识
https://developer.android.google.cn/courses/android-basics-kotlin/course -
Navigation的示例代码学习路径
NavigationComponents-Tutorials -
一个国外公司做的部分Android代码教程:
https://github.com/SmartToolFactory