替代FrameLayout作为Fragment的容器。
解决了FrameLayout在Fragment过渡动画 View显示次序问题,另外支持导航功能。
Android项目默认会依赖Fragment库,也可手动添加依赖:
dependencies {
def fragment_version = "1.5.5"
implementation "androidx.fragment:fragment:$fragment_version"
// 支持kotlin一些拓展方法
implementation "androidx.fragment:fragment-ktx:$fragment_version"
// 用于Fragment的单元测试,可选
debugImplementation "androidx.fragment:fragment-testing:$fragment_version"
}
只需把原来FrameLayout替换成FragmentContainerView 即可:
<androidx.fragment.app.FragmentContainerView
android:id="@+id/fragment_container_view"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<androidx.fragment.app.FragmentContainerView
android:id="@+id/fragment_container_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:name="com.example.ExampleFragment"
android:tag="my_tag" />
和FrameLayout作为容器时一样,使用FragmentManager的方法:
负责添加、替换、移除事务提交和后退
getSupportFragmentManager().beginTransaction()
.setReorderingAllowed(true)
.add(R.id.fragment_container_view, ExampleFragment.class, null)
.commit();
和Activity类似,设置窗体动画和过渡动画:
具体看官方文档:https://developer.android.com/guide/fragments/animate
Navigation组件允许使用导航图,来设计页面的导航跳转。
FragmentContainerView作为Fragment的容器,对于单个Activity多个Fragment来设计的APP,使用导航可以方便实现。
<androidx.fragment.app.FragmentContainerView
android:name="androidx.navigation.fragment.NavHostFragment"
app:navGraph="@navigation/nav_graph"
app:defaultNavHost="true"
android:id="@+id/main_content"
android:layout_width="match_parent"
android:layout_height="match_parent" />
在res目录创建 navigation 资源目录。然后
右键 New -> Navigation Resource File 创建 导航图文件。
<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/mainFragment">
<fragment
android:id="@+id/mainFragment"
android:name="com.example.fragmetndemo.MainFragment"
android:label="fragment_main"
tools:layout="@layout/fragment_main" />
navigation>
navigation标签下,可包含 activity/fragment/dialog/include 元素,它们分别对应
NavController 负责跳转页面功能。
可是使用 目标id、action、deeplink 等导航到目标。
在fragment/activity标签内,添加 action deeplink:
<action
android:id="@+id/action_main_to_second"
app:destination="@+id/secondFragment"
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" />
<deepLink app:uri="android-app://com.example.fragmentdemo/second" />
代码里使用NavControler导航:
// 使用fragment id跳转
findNavController().navigate(R.id.secondFragment)
// 使用action跳转
findNavController().navigate(R.id.action_main_to_second)
// 使用deepLink,跨模块跳转
val request = NavDeepLinkRequest.Builder
.fromUri("android-app://com.example.fragmentdemo/second".toUri())
.build()
findNavController().navigate(request)
详细说明:
1. 在使用时,添加gradle插件:
// 在项目的顶级build.gradle 添加:
plugins {
id 'androidx.navigation.safeargs' version '2.5.3' apply false
}
如果顶级build.gradle使用的是dependencies方式,则使用:
buildscript {
dependencies {
classpath "androidx.navigation:navigation-safe-args-gradle-plugin:2.5.3"
}
}
在模块build.gradle中添加:
plugins {
id 'androidx.navigation.safeargs'
}
2. 在目标标签内,添加 argument 标签,声明参数名、类型、默认值。
<argument
android:name="count"
app:argType="integer"
android:defaultValue="0" />
非基本类型,可以使用 app:nullable 声明是否可空。
3. 代码调用:
// 通过Bundle传数据
findNavController().navigate(
R.id.action_main_to_second,
bundleOf(
"count" to 1
)
)