声明:个人笔记,无参考学习价值
部分内容摘抄自:
作者:七适散人
链接:https://www.jianshu.com/p/d37f5132db3c
1.res-->Android Resource File-->navigation-->xxx.xml
2.xxx.xml中将需要的多个fragment进行管理,可以指定Actions,Argments
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/main_tab_navigation"
xmlns:tools="http://schemas.android.com/tools"
⭐️ app:startDestination="@id/homepageFragment">
<fragment
tools:layout="@layout/fragment_homepage"
<--如果配合bottomNavigationView和menu使用的话,这里的id要和menu的id相同-->
⭐️ android:id="@+id/homepageFragment"
android:name="com.myself.mvpdemo.maintap.view.fragment.HomepageFragment"
android:label="HomepageFragment" >
<action
android:id="@+id/action_homepageFragment_to_qandAfragment"
app:destination="@id/qandAfragment" />
<argument
android:name="safeData"
app:argType="integer"
android:defaultValue="12" />
</fragment>
</navigation>
tools:layout="@layout/fragment_homepage" : fragment的layout
android:name="" fragment的路径
3 在actiivty中的引用,定义一个fragment:
- 第一种:在xml文件中定义
<fragment
android:id="@+id/nav_fragment"
⭐️ android:name="androidx.navigation.fragment.NavHostFragment"
⭐️ app:navGraph="@navigation/main_tab_navigation"
⭐️ app:defaultNavHost="true"
android:layout_width="match_parent"
android:layout_weight="1"
android:layout_height="0dp"/>
android:name 是 NavHostFragment,它实现了 NavHost,这是一个用于放置管理 destination 的空视图。
app:navGraph 用于将这个 NavHostFragment 和 xxx.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_navigation)
val finalHost = NavHostFragment.create(R.navigation.nav_graph)
supportFragmentManager.beginTransaction()
.replace(R.id.frame_layout, finalHost)
.setPrimaryNavigationFragment(finalHost) // 等价于 xml 中的 app:defaultNavHost="true"
.commit()
}
4.处理跳转
跳转通过 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)
button.onClick {
// NavHostFragment.findNavController(this@FirstFragment)
// .navigate(R.id.action_nav_graph_first_fragment_to_nav_graph_second_fragment)
Navigation.findNavController(getView()!!)
.navigate(R.id.action_nav_graph_first_fragment_to_nav_graph_second_fragment)
}
}
5.添加跳转动画
可在可视化Design中操作,生成代码:
<fragment
android:id="@+id/nav_graph_first_fragment"
android:name="pot.ner347.androiddemo.navigation.FirstFragment"
android:label="first"
tools:layout="@layout/fragment_first">
<action
android:id="@+id/action_nav_graph_first_fragment_to_nav_graph_second_fragment"
app:destination="@id/nav_graph_second_fragment"
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" />
</fragment>
支持 View 动画和属性动画,enterAnim 和 exitAnim 是去往栈里添加一个 destination 时两个 destination 的动画,popEnterAnim 和 popExitAnim 是从栈里移除一个 destination 时的动画。
6.传递数据
要跳转到 SecondFragment,要往 SecondFragment 里带数据,在目的 Fragment 里添加 <argument>
<!-- nav_graph.xml -->
<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
... >
<fragment
android:id="@+id/nav_graph_second_fragment"
android:name="pot.ner347.androiddemo.navigation.SecondFragment"
android:label="second"
tools:layout="@layout/fragment_second" >
<argument android:name="name" android:defaultValue="Max"/>
</fragment>
</navigation>
FirstFragment 添加数据
button.onClick {
val bundle = bundleOf("name" to "silas")
Navigation.findNavController(getView()!!)
.navigate(R.id.action_nav_graph_first_fragment_to_nav_graph_second_fragment, bundle)
}
SecondFragment 获取数据
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
arguments?.getString("name")?.let { toast("hello $it") }
return inflater.inflate(R.layout.fragment_second, container, false)
}
如果 FirstFragment 没有带数据,那么 SecondFragment 将收到默认值 “Max”。