Android 无限片段导航

Android Navigation for infinite Fragment

目标Fragment是否必须在导航图中注册?比如我想通过Fragment展示一个多级目录,每个Fragment展示一个目录,那么我就无法在导航视图中注册所有的Fragment,因为我不知道需要多少个Fragment。
我该怎么办?

--------添加--------

可能我没有描述清楚我的问题,我目前的需求如下图:

this is my needs

现在使用ViewPager和FragmentStatePagerAdapter动态增删fragment,但是想迁移到Navigation,不知道有没有办法。

您的导航图中应该只有一个 DirectoryFragment。该片段将有一个 argument 指示应显示的目录:

<fragment android:id="@+id/directory_fragment"
    android:name="com.example.DirectoryFragment">
    <argument
        android:name="directory"
        app:argType="string"
        android:defaultValue="/" />
</fragment>

然后,您可以navigate using the id:

File directory = ...
directoryButton.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        Bundle arguments = new Bundle();
        arguments.putString("directory", directory.getAbsolutePath());
        Navigation.findNavController(view).navigate(
            R.id.directory_fragment, arguments);
    }
});

通过调用 navigate(),您的 DirectoryFragment 的一个新实例被创建并添加到返回堆栈,显示您作为参数传入的目录。

这是您所需的最低限度。强烈建议您 connect your destinations via actions, which allows you to add transitions between your destinations and enables using Safe Argsnavigate() 调用添加类型安全。

这将允许您编写如下内容:

<fragment android:id="@+id/directory_fragment"
    android:name="com.example.DirectoryFragment">
    <argument
        android:name="directory"
        app:argType="string"
        android:defaultValue="/" />
    <action android:id="@+id/show_subdirectory"
        app:destination="@+id/directory_fragment"
        app:enterAnim="@anim/slide_in_right"
        app:exitAnim="@anim/slide_out_left"
        app:popEnterAnim="@anim/slide_in_left"
        app:popExitAnim="@anim/slide_out_right"/>
</fragment>

并通过以下方式导航:

File directory = ...
directoryButton.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        Navigation.findNavController(view).navigate(
            DirectoryFragmentDirections.showSubdirectory()
                .setDirectory(directory.getAbsolutePath()));
    }
});