Android Navigation Architecture Component 使用详解

一、Navigation 是什么

Navigation 是 Google 新推出的库,其作用简单的说就是用于简化界面间跳转的,Activity 和 Fragment 都可以 [ Google Navigation 官方文档 ] [ Google 官方 Navigation Samples ] [这个也是 Google 官方用了 Navigation 的 Samples] 可以 checkout 下来看看,我在研究 Navigation 时也用 Navigation 随手做了小项目 [项目源码]

二、准备工作

Navigation 是 Android Studio 3.2 才有的功能,所以要先下载 Android Studio 3.2, 目前 Android Studio 3.2 是预览版,正式版目前是 3.1.3,
[Androi Studio 3.2 下载页] [Androi Studio 3.2 下载链接]
运行结果截图
运行结果截图

三、Navigation 的用法

(一)基本用法

下载完 Android Studio 3.2 后打开程序新建个项目,打开 app 下的 build.gradle 导入 Navigation

dependencies {
    implementation "android.arch.navigation:navigation-fragment:1.0.0-alpha02"
    implementation "android.arch.navigation:navigation-ui:1.0.0-alpha02"
}

新建个Fragment

public class FirstFragment extends Fragment {
   
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_simple_first, container, false);
    }
}

布局

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".simple.FirstFragment">
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        android:textSize="30sp"
        android:text="我是第一个 Fragment" />
</android.support.constraint.ConstraintLayout>

在 res 目录右键选择 New -> Android Resource File
运行结果截图
新建个 Navigation 资源文件
运行结果截图
新建完成就会在 res 目录下生成 navigation 目录和文件,就是下面那样的 根元素是 navigation
运行结果截图
运行结果截图
接下来就把刚刚写的 Fragment 写进去,打上左尖括号 < Android Studio 就会提示
运行结果截图
这里选择 fragment 标签,选择了 fragment 后再打个空格又有提示
运行结果截图
这里的 id 就像写布局的 id 那样需要给个 id 才能找到它,name 就是说明是哪个 Fragment 类名的,像下面那样

<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android">
    <fragment
        android:id="@+id/nav_simple_first_frag"
        android:name="com.ce.navigationtest.simple.FirstFragment"
        android:label="first frag" >
    </fragment>
</navigation>

这时可以点击下面的 Design 看一下
运行结果截图
运行结果截图
这什么呀,Preview Unavailable? 预览不可用?(黑人问号脸),其实这里是少写了个 layout 的属性,Android Studio 也没提示,可能是预览版的还不够完善的原因,layout 属性是要用到 tools 的命名空间的,加上 layout 后如下,

<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">
    <fragment
        android:id="@+id/nav_simple_first_frag"
        android:name="com.ce.navigationtest.simple.FirstFragment"
        android:label="first frag"
        tools:layout="@layout/fragment_simple_first">
    </fragment>
</navigation>

再去 Design 看一下,这回就有了
运行结果截图
这里先告一段落了(顺便挖了个坑),现在去写 Activity 里的布局,Activity 的布局该怎么写?这里要用到 NavHost 来托管 Navigation,NavHost 是个接口,默认是用 NavHostFragment 来托管,NavHostFragment 是实现了 NavHost 接口的,进去 NavHostFragment 看一下

/**
 * NavHostFragment provides an area within your layout for self-contained navigation to occur.
 *
 * <p>NavHostFragment is intended to be used as the content area within a layout resource
 * defining your app's chrome around it, e.g.:</p>
 *
 * <pre class="prettyprint">
 *     <android.support.v4.widget.DrawerLayout
 *             xmlns:android="http://schemas.android.com/apk/res/android"
 *             xmlns:app="http://schemas.android.com/apk/res-auto"
 *             android:layout_width="match_parent"
 *             android:layout_height="match_parent">
 *         <fragment
 *                 android:layout_width="match_parent"
 *                 android:layout_height="match_parent"
 *                 android:id="@+id/my_nav_host_fragment"
 *                 android:name="androidx.navigation.fragment.NavHostFragment"
 *                 app:navGraph="@xml/nav_sample"
 *                 app:defaultNavHost="true" />
 *         <android.support.design.widget.NavigationView
 *                 android:layout_width="wrap_content"
 *                 android:layout_height="match_parent"
 *                 android:layout_gravity="start"/>
 *     </android.support.v4.widget.DrawerLayout>
 * </pre>
 *
 * <p>Each NavHostFragment has a {@link NavController} that defines valid navigation within
 * the navigation host. This includes the {@link NavGraph navigation graph} as well as navigation
 * state such as current location and back stack that will be saved and restored along with the
 * NavHostFragment itself.</p>
 *
 * <p>NavHostFragments register their navigation controller at the root of their view subtree
 * such that any descendant can obtain the controller instance through the {@link Navigation}
 * helper class's methods such as {@link Navigation#findNavController(View)}. View event listener
 * implementations such as {@link android.view.View.OnClickListener} within navigation destination
 * fragments can use these helpers to navigate based on user interaction without creating a tight
 * coupling to the navigation host.</p>
 */
public class NavHostFragment extends Fragment implements NavHost {
   
  ......
}

哇,注释中怎么写都给我们准备好了,厉害厉害,我们拿来用就好了,我们先简单点

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.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=".simple.SimpleActivity">
    <fragment
        android:id="@+id/frag_nav_simple"
        android:name="androidx.navigation.fragment.NavHostFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:navGraph="@navigation/nav_simple"
        app:defaultNavHost="true" />
</android.support.constraint.ConstraintLayout>

navGraph 属性就是写刚才我们写的 nagation 文件,defaultNavHost 这个是和返回键相关的,和这一块相关的[官方文档]
到这里可以去运行一下了,啥情况,咋崩溃了,刚才挖的什么坑,来看一下日志
运行结果截图
no start destination defined via app:startDestination for the root navigation 黑人问号脸,有没有注意过 navigation 文件的 navigation 标签有个警告,鼠标移上去也有提示 No start destination specified
运行结果截图
其实这里是要在 navigation 文件里指定是从哪里开始的,没有指定就会报错,因为不知道哪个是出发点,就像地图得知道起始位置和目的地才可以导航,修改一下 navigation 文件的内容,根 navigation 添加上 startDestination 属性,

<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    app:startDestination="@id/nav_simple_first_frag">
    <fragment
        android:id="@+id/nav_simple_first_frag"
        android:name="com.ce.navigationtest.simple.FirstFragment"
        android:label="first frag"
        tools:layout="@layout/fragment_simple_first">
    </fragment>
</navigation>

再运行一下吧,这回不坑了,
运行结果截图

(二)界面间跳转

一个 Fragment 怎么过瘾,再来个 Fragment

public class SecondFragment extends Fragment {
   
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_simple_second, container, false);
    }
}

布局

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.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=".simple.SecondFragment">
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="我是第二个 Fragment"
        android:textSize="30sp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>

把第一个 Fragment 的布局也改一下,

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.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=".simple.FirstFragment">
    <android.support.v7.widget.AppCompatButton
        android:id="@+id/btn_to_second_fragment"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="去第二个Fragment"
        android:textAllCaps="false"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>

把第二个 Fragment 也添加到 Navigation 文件里,和第一个 Fragment 差不多

<?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"
    app:startDestination="@id/nav_simple_first_frag">
    ......
    <fragment
        android:id="@+id/nav_simple_second_frag"
        android:name="com.ce.navigationtest.simple.SecondFragment"
        android:label="second frag"
        tools:layout="@layout/fragment_simple_second">
    </fragment>
</navigation>

那第一个 Fragment 怎么和 第二个 Fragment 关联起来?很简单,有 action

  • 17
    点赞
  • 39
    收藏
    觉得还不错? 一键收藏
  • 24
    评论
Android Navigation 是一个用于管理应用程序导航的框架,它可以帮助您轻松地实现常见的导航模式,例如抽屉导航、选项卡导航、底部导航和导航折叠等。 以下是使用 Android Navigation 进行导航的一般步骤: 1. 添加 Navigation 组件库:在 build.gradle 文件中添加以下依赖项: ``` dependencies { def nav_version = "2.3.1" implementation "androidx.navigation:navigation-fragment-ktx:$nav_version" implementation "androidx.navigation:navigation-ui-ktx:$nav_version" } ``` 2. 创建导航图:在 res 文件夹中创建一个名为 nav_graph.xml 的 XML 文件。在此文件中,您可以定义应用程序的所有目标目的地以及它们之间的导航关系。 3. 配置 NavHost:在您的布局文件中添加一个 NavHostFragment,它将负责管理您的应用程序的导航。例如: ``` <fragment android:id="@+id/nav_host_fragment" android:name="androidx.navigation.fragment.NavHostFragment" android:layout_width="match_parent" android:layout_height="match_parent" app:navGraph="@navigation/nav_graph" /> ``` 4. 配置导航栏:在您的 Activity 或 Fragment 中使用 Navigation UI 库配置您的导航栏。例如: ``` val navController = findNavController(R.id.nav_host_fragment) bottom_nav.setupWithNavController(navController) ``` 5. 导航:使用 NavController 对象执行导航操作。例如,您可以使用以下代码在应用程序中导航到目标目的地: ``` findNavController().navigate(R.id.action_homeFragment_to_detailFragment) ``` 这是一个简单的例子,但是使用 Android Navigation 进行导航可以更加复杂。您可以在官方文档中找到更多信息和示例:https://developer.android.com/guide/navigation/

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 24
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值