使用导航组件时未设置Fragment的id和tag

fla*_*rud 5 android android-fragments

我遇到的问题是我的片段的 id 和标签未设置,尽管我在我的中指定了它们mobile_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/mobile_navigation"
    app:startDestination="@+id/nav_frag1">

    <fragment
        android:id="@+id/nav_frag1"
        android:tag="abcdef"
        android:name="org.example.myproject.MyFragment"
        android:label="@string/menu_frag1"
        tools:layout="@layout/fragment_frag1" />

    ...

</navigation>
Run Code Online (Sandbox Code Playgroud)

当我尝试在我的片段中通过编程方式访问 id 和标记时,this.getId()或者所有片段的this.getTag()id 始终是相同的非常高的整数(比 max int 稍小)并且标记为null

导航是放在我的主要活动中的。该代码基本上是Android Studio 创建的示例抽屉导航项目。我没有改变任何事情。

public class MainActivity extends AppCompatActivity {

    private AppBarConfiguration mAppBarConfiguration;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);

        Toolbar toolbar = findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        DrawerLayout drawer = findViewById(R.id.drawer_layout);
        NavigationView navigationView = findViewById(R.id.nav_view);
        mAppBarConfiguration = new AppBarConfiguration.Builder(
                R.id.frag1, R.id.frag2, R.id.frag3)
                .setDrawerLayout(drawer)
                .build();
        NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
        NavigationUI.setupActionBarWithNavController(this, navController, mAppBarConfiguration);
        NavigationUI.setupWithNavController(navigationView, navController);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public boolean onSupportNavigateUp() {
        NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
        return NavigationUI.navigateUp(navController, mAppBarConfiguration)
                || super.onSupportNavigateUp();
    }

}
Run Code Online (Sandbox Code Playgroud)

我是否遗漏了有关 id 和标签设置方式的信息?

编辑:可以在https://github.com/flauschtrud/FragmentTagAndIdTest找到演示意外行为的示例项目

her*_*hes 0

将片段标记转换导航标记,它是一个目的地(此处为目的地剖析),因此您可以定义:id、name、label。

<navigation>
    <fragment></fragment>
</navigation>
Run Code Online (Sandbox Code Playgroud)

与xml 布局中的片段标签不同,其中实现获取android:tag attr并在从android:name扩充 Fragment 时使用它。

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

   <fragment
      android:id="@+id/someFragment"
      android:tag="someTagNameToSomeFragment"
      android:name="com.somepackagename.SomeFragment"/>
</LinearLayout>
Run Code Online (Sandbox Code Playgroud)

android:id也会发生同样的情况,它是该目的地的 id 资源,而不是Fragment id。我们有两种方法为 Fragment 设置 id,要么从 xml 布局文件(如上面的示例),要么通过事务。从事务(从活动提交 kotlin 扩展):

supportFragmentManager.commit { add(R.id.someFragment, SomeFragment()) }
Run Code Online (Sandbox Code Playgroud)

我假设R.id.nav_host_fragment是您为 xml 布局上定义的 NavHostFragment 容器(视图)提供的 id。在这种情况下,每次导航到新目的地时,之前的 Fragment View 都会被销毁,并会创建新的 Fragment 及其视图。这些情况下的 Fragment id 将为R.id.nav_host_fragment(在 xml 布局上定义的 NavHostFragment 容器(视图)id)。