JetPack 系列——Navigation(一),flutter 安装 androidsdk
classpath "androidx.navigation:navigation-safe-args-gradle-plugin:2.3.2"
2.2 创建导航图
Res 右键 New Resource File 创建一个资源文件,类型名字写成 nav_graph,类型选择 Navigation
就会创建一个导航图文件,里边包含以下内容:
<navigation xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"android:id="@+id/nav_graph"></navigation>
2.3 添加 NavHostFragment
NavHostFragment 是一个特殊的 Fragment,需要添加到 Activity 的布局文件中。
<androidx.fragment.app.FragmentContainerViewandroid:layout_width="match_parent"android:layout_height="wrap_content"app:layout_constraintTop_toTopOf="parent"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintLeft_toLeftOf="parent"app:layout_constraintRight_toRightOf="parent"android:name="androidx.navigation.fragment.NavHostFragment"app:defaultNavHost="true"app:navGraph="@navigation/nav_graph"/>
name 属性指定 NavHost 的实现类,这里是 NavHostFragment。
defaultNavHost="true" 拦截系统返回键,当用户按下返回键时系统会将正在展示的 Fragment 返回。
navGraph 属性 关联导航图。
2.4 为导航图添加目的地
首先需要创建两个 Fragment,FirstFragment 和 SecondFragment,并且将这两个 Fragment 关联到我们的导航文件中。
<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/fragmentFirst"><fragmentandroid:id="@+id/fragmentFirst"android:name="com.example.navigationtest.FirstFragment"android:label="fragment_first"tools:layout="@layout/fragment_first"/><fragmentandroid:id="@+id/fragmentSecond"android:name="com.example.navigationtest.SecondFragment"android:label="fragment_second"tools:layout="@layout/fragment_second"/></navigation>
id 必填项,后面 fragment 跳转的时候要用到
name Fragment 的全路径
layout Fragment 的布局
2.5 添加跳转 action
为了达到跳转的目的,需要为 fragment 添加用于跳转的 action。
<actionandroid:id="@+id/first_to_second"app:destination="@id/fragmentSecond"/>
其中,destination 指定了要跳转到的 fragment,这也就是为什么在导航文件中创建 fragment 时要指定 id 的原因。定义好 action 之后,在 FirstFragment 中添加跳转的点击事件,使用 Navigation 将页面导航到 SecondFragment 中:
val view=inflater.inflate(R.layout.fragment_first, container, false)val binding = FragmentFirstBinding.bind(view)binding.btnFirst.setOnClickListener {Navigation.findNavController(view!!).navigate(R.id.first_to_second)}
navigate 方法接收的参数就是前面定义的 action。
2.6 添加转场动画
刚刚创建的跳转过程默认是没有动画效果的,现在把转场动画效果加上。修改导航文件中的 action,添加动画属性:
<actionandroid:id="@+id/first_to_second"app:destination="@id/fragmentSecond"app:enterAnim="@anim/nav_default_enter_anim"app:exitAnim="@anim/nav_default_exit_anim"app:popEnterAnim="@anim/nav_default_pop_enter_anim"app:popExitAnim="@anim/nav_default_pop_exit_anim"/>
运行程序,切换页面时就可以看到动画效果。
2.7 使用 NavigationUI
2.7.1 NavigationUI 的意义
在 Navigation 组件中,导航图是很重要的一部分,可以帮助我们了解页面之间的关系,并且快速完成页面间的切换,而在页面切换的过程中还伴随着菜单栏的变化。对于不同的页面,AppBar 中的 menu 菜单很可能是不一样的。并且 AppBar 中的按钮和菜单同样可能承担着页面切换的工作,为了统一管理,JetPack 引入了 NavigationUI 组件来将 AppBar 与 Navigation 中的导航图关联到一起。
2.7.2 NavigationUI 的使用分析
首先需要创建一个 settingFragment 并且关联到导航图文件中
<fragmentandroid:id="@+id/fragmentSetting"android:name="com.example.navigationtest.SettingFragment"tools:layout="@layout/fragment_setting"android:label="fragment_setting"/>
创建菜单文件 menu_settings.xml
<?xml version="1.0" encoding="utf-8"?><menu xmlns:android="http://schemas.android.com/apk/res/android"><itemandroid:id="@id/fragmentSetting"android:icon="@drawable/ic_launcher_background"android:title="设置" /></menu>
item 的 id 需要和导航文件中的 settingFragment 保持一致,否则会无法跳转到 settingFragment。
在 activity 中实现跳转
class NavigationActivity : AppCompatActivity() {private var navController: NavController? =nullprivate var appBarConfig:AppBarConfiguration?=nulloverride fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)val binding = ActivityNavigationBinding.inflate(layoutInflater)setContentView(binding.root)// navController = Navigation.findNavController(this@NavigationActivity,R.id.nav_host_fragment)val navHost = supportFragmentManager.findFragmentById(R.id.nav_host_fragment)navController = navHost!!.findNavController()appBarConfig = AppBarConfiguration(navController!!.graph)NavigationUI.setupActionBarWithNavController(this, navController!!, appBarConfig!!)
}
override fun onCreateOptionsMenu(menu: Menu?): Boolean {super.onCreateOptionsMenu(menu)menuInflater.inflate(R.menu.menu_settings,menu)return true}
override fun onOptionsItemSelected(item: MenuItem): Boolean {return NavigationUI.onNavDestinationSelected(item,
navController!!)||super.onOptionsItemSelected(item)}
评论