本文章结束后完成的效果
导入库
Deps.kt
const val navigation = "2.0.0"
const val navigation_ui = "2.1.0"
const val navigation_fragment ="androidx.navigation:navigation-fragment-ktx:${Versions.navigation}"
const val navigation_ui = "androidx.navigation:navigation-ui-ktx:${Versions.navigation_ui}"
build.gradle
implementation Deps.navigation_fragment
implementation Deps.navigation_ui
如果你要使用SafeArgs插件,还要在项目目录下的build.gradle文件添加:
buildscript {
ext.navigationVersion = "2.0.0"
dependencies {
classpath "androidx.navigation:navigation-safe-args-gradle-plugin:$navigationVersion"
}
}
以及模块下面的build.gradle文件添加:
apply plugin: 'kotlin-android-extensions'
apply plugin: 'androidx.navigation.safeargs'
名词 | 解释 |
---|---|
Navigation Graph(New XML resource) | 如我们的第一张图所示,这是一个新的资源文件,用户在可视化界面可以看出他能够到达的Destination(用户能够到达的屏幕界面),以及流程关系。 |
NavHostFragment(Layout XML view) | 当前Fragment的容器 |
NavController(Kotlin/Java object) | 导航的控制者 |
创建5个Fragment和一个Activity
Fragment参考代码
class HomeFragment : BaseFragment() {
override fun getLayoutResId() = R.layout.fragment_home
override fun initView() {
}
override fun initData() {
}
}
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:background="@color/colorPrimaryDark"
android:layout_width="match_parent"
android:layout_height="match_parent">
</androidx.constraintlayout.widget.ConstraintLayout>
1.创建Navigation Graph导航
创建基础目录:资源文件res
目录下创建navigation
目录 -> 右击navigation
目录New一个Navigation resource file
创建一个Destination
,添加fragment
,在此之前,我已经写好了一个
tab_navigation.xml
代码
<?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/tab_navigation"
app:startDestination="@id/homeFragment"
tools:ignore="UnusedNavigation">
<fragment
android:id="@+id/homeFragment"
android:name="com.wanandroid.ui.home.HomeFragment"
android:label="HomeFragment" />
<fragment
android:id="@+id/blogFragment"
android:name="com.wanandroid.ui.blog.BlogFragment"
android:label="BlogFragment" />
<fragment
android:id="@+id/searchFragment"
android:name="com.wanandroid.ui.search.SearchFragment"
android:label="SearchFragment" />
<fragment
android:id="@+id/projectFragment"
android:name="com.wanandroid.ui.project.ProjectFragment"
android:label="ProjectFragment" />
<fragment
android:id="@+id/profileFragment"
android:name="com.wanandroid.ui.profile.ProfileFragment"
android:label="ProfileFragment" />
</navigation>
属性 | 描述 |
---|---|
app:startDestination | 默认的起始位置 |
android:name | 属性代表对应的Fragment路径 |
action | 代表该Fragment存在的跳转事件 |
2.建立NavHostFragment
穿件一个新的MainActivity
,在activity_main.xml
文件中
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<fragment
android:id="@+id/navigation_host"
android:name="androidx.navigation.fragment.NavHostFragment"
app:navGraph="@navigation/tab_navigation"
app:defaultNavHost="true"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintVertical_weight="1"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="@+id/bnv_view"
/>
<!--app:labelVisibilityMode="labeled" 解决安卓底部导航大于3个时标题隐藏的问题-->
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/bnv_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@android:color/white"
app:layout_constraintBottom_toBottomOf="parent"
app:menu="@menu/menu_main"
app:labelVisibilityMode="labeled"
tools:ignore="MissingClass,MissingConstraints" />
</androidx.constraintlayout.widget.ConstraintLayout>
添加BottomNavigationView menu,menu_main.xml
;
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<!--各个item绑定的android:id 需要个navigation 中fragment android:id 相对应-->
<item
android:id="@+id/homeFragment"
android:icon="@drawable/ic_home_black_24dp"
android:title="@string/home" />
<item
android:id="@+id/blogFragment"
android:icon="@drawable/ic_blog"
android:title="@string/blog" />
<item
android:id="@+id/searchFragment"
android:icon="@drawable/search"
android:title="@string/search" />
<item
android:id="@+id/projectFragment"
android:icon="@drawable/ic_dashboard_black_24dp"
android:title="@string/project_type" />
<item
android:id="@+id/profileFragment"
android:icon="@drawable/ic_profile"
android:title="@string/me" />
</menu>
3. 创建NavController
MainActivity
中的处理也十分简单
class MainActivity : BaseActivity() {
lateinit var bottomNavigationView: BottomNavigationView
override fun getLayoutResId() = R.layout.activity_main
override fun onCreate(savedInstanceState: Bundle?) {
setTheme(R.style.AppTheme)
super.onCreate(savedInstanceState)
}
override fun initView() {
bottomNavigationView = findViewById(R.id.bnv_view)
val host: NavHostFragment = supportFragmentManager.findFragmentById(R.id.navigation_host) as NavHostFragment
val navController = host.navController
bottomNavigationView.setupWithNavController(navController)
}
override fun initData() {
}
}
实现之后的效果
界面跳转
利用ID导航示例
btnLogin.setOnClickListener {
// 设置动画参数
val navOption = navOptions {
anim {
enter = R.anim.slide_in_right
exit = R.anim.slide_out_left
popEnter = R.anim.slide_in_left
popExit = R.anim.slide_out_right
}
}
// 参数设置
val bundle = Bundle()
bundle.putString("name","TeaOf")
findNavController().navigate(R.id.login, bundle,navOption)
}
致谢