美文网首页
[学习]JetPack 中的 Navigation(三)

[学习]JetPack 中的 Navigation(三)

作者: 吴敬悦 | 来源:发表于2021-01-30 16:25 被阅读0次

    现在我们需要使用 Navigation 里面的导航菜单,而不是使用默认 Activity 的导航菜单。

    如果可以通过官网的方式学习,就尽量不要使用视频的方式,因为学习的时候大部分是学习最新的,而视频很大概率是很久以前的。

    学到了两种方式。

    提前做好准备,打开文件 res/navigation/ 下你的 xml 文件,点击每一个 Fragment 页面,给它们设置对应的标题,在 Design 下的右边的 id 下,有一个属性是 label ,填写上对应的名称即可。

    1. 使用 Activity 中的导航菜单

    默认 Activity 的导航菜单显示的是标题和返回按钮,而返回按钮是返回到上一个 Activity ,而我们的 Navigation 是在一个 Activity 中的,如果当前 Activity 位于栈的最上层,我学习的代码就是让所有的 Fragment 都在 MainActivity 中,因为无论我怎么跳转都在 MainActivity 中。所以现在有两个两个任务:

    1. 首先跳转到下一页以后会出现返回按钮;
    2. 点击返回按钮能够正常返回上一个 Navigation 页面。

    由于第二个需要在第一个完成的基础上才能看得出效果,所以我们按上面的步骤进行。

    原本的效果:

    默认效果
    打开承载了 FragmentActivityjava 文件,我这里是 MainActivity.java,在 onCreate 方法下添加如下代码:
    @Override
    protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_main);
      NavHostFragment navHostFragment = (NavHostFragment)getSupportFragmentManager().findFragmentById(R.id.nav_host_fragment);
      NavController navController = navHostFragment.getNavController();
      appBarConfiguration = new AppBarConfiguration.Builder(navController.getGraph()).build();
      NavigationUI.setupActionBarWithNavController(this, navController, appBarConfiguration);
    }
    

    android 官方获取 navController 是直接获取的 Navigation.findNavController(this, R.id.nav_host_fragment); ,如果很不幸你也这样写了,那么就会出现的错误:

    Caused by: java.lang.IllegalStateException: Activity com.example.learnjetpack.MainActivity@b516fb8 does not have a NavController set on 2131230962
    

    只要修改成我上面那样就可以解决这个问题,至于原因我现在解释不了,以后会补全。上面的代码就是托管原本 ActivityBar

    Navigation托管Activity后的效果
    这样第一个完成了,至于第二个,只需要重写原本 Activity 的返回的逻辑:
    @Override
    public boolean onSupportNavigateUp() {
      NavHostFragment navHostFragment = (NavHostFragment)getSupportFragmentManager().findFragmentById(R.id.nav_host_fragment);
      NavController navController = navHostFragment.getNavController();
      return NavigationUI.navigateUp(navController, appBarConfiguration)
                || super.onSupportNavigateUp();
    }
    

    接下来看看最终的效果。

    最终的效果
    我还遇到了一个问题,之前我的 MainActivitytheme 设置 android:theme="@style/Theme.AppCompat.Light.NoActionBar" ,结果出现了下面的错误:
         Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void androidx.appcompat.app.ActionBar.setTitle(java.lang.CharSequence)' on a null object reference
    

    把这个改掉即可,因为设置 NoActionBar 了,结果又让显示,固然手机就会耍小脾气。这个是在 AndroidManifest.xml 中设置的。

    2. 使用 Toolbar

    这种方式就是不用默认的,而是自定义;所以这个很容易想到需要将 MainActivitytheme 改为上面会出现错误的情况。打开 AndroidManifest.xml 文件,修改对应的 Activitytheme,修改成 @style/Theme.AppCompat.Light.NoActionBar

    没有bar的效果
    打开对应的 Activity 下的布局文件,我这里是 MainActivity ,布局文件为 activity_layout.xml ,在 androidx.fragment.app.FragmentContainerView 上添加:
    <androidx.appcompat.widget.Toolbar
          android:id="@+id/toolbar"
          android:layout_width="0dp"
          android:layout_height="?attr/actionBarSize"
          app:layout_collapseMode="pin"
          app:layout_constraintBottom_toTopOf="@+id/nav_host_fragment"
          app:layout_constraintEnd_toEndOf="parent"
          app:layout_constraintStart_toStartOf="parent"
          app:layout_constraintTop_toTopOf="parent" />
    

    先看看效果:


    自定义头部的效果

    接下来让其显示内容。

    同样在 Activity 中的添加:

    @Override
    protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_main);
      NavHostFragment navHostFragment = (NavHostFragment)getSupportFragmentManager().findFragmentById(R.id.nav_host_fragment);
      NavController navController = navHostFragment.getNavController();
      AppBarConfiguration appBarConfiguration =
                new AppBarConfiguration.Builder(navController.getGraph()).build();
      Toolbar toolbar = findViewById(R.id.toolbar);
      NavigationUI.setupWithNavController(
                toolbar, navController, appBarConfiguration);
    }
    

    这种方式 Navigation 会自动托管 Toolbar ,这样就可以轻松实现上面的效果,其他的代码就不需要,看效果:

    使用 Toolbar 最终的效果

    相关文章

      网友评论

          本文标题:[学习]JetPack 中的 Navigation(三)

          本文链接:https://www.haomeiwen.com/subject/kkxktltx.html