导航组件在片段中初始化NavController的位置

时间:2020-03-05 08:49:35

标签: android android-architecture-navigation

在我的MainFragment类中,当尝试在onCreateView中初始化NavController时,出现了RuntimeException,其原因是:

IllegalStateException: View android.widget.RelativeLayout{cf3c6de V.E...... ......I. 0,0-0,0 #7f0800d7 app:id/parentLayout} does not have a NavController set

如果NavController是通过onViewCreated方法初始化的,它将可以正常工作。这是为什么?我无法从教程/文档中弄清楚。

fragment_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/parentLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainFragment">

    <Button...>

    <Button...>

    <Button...>

</RelativeLayout>

MainFragment.java

public class MainFragment extends Fragment {

    private NavController navController;
    private Button bViewTransaction, bSendMoney, bViewBalance;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_main, container, false);

        bViewTransaction = view.findViewById(R.id.view_transactions_btn);
        bSendMoney = view.findViewById(R.id.send_money_btn);
        bViewBalance = view.findViewById(R.id.view_balance_btn);

//         IllegalStateException
        navController = Navigation.findNavController(view);

        return view;

    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

//         NO problem
//        navController = Navigation.findNavController(view);

        bViewTransaction.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                navController.navigate(R.id.action_mainFragment_to_viewTransactionFragment);
            }
        });

        bSendMoney.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                navController.navigate(R.id.action_mainFragment_to_chooseRecipientFragment);
            }
        });

        bViewBalance.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                navController.navigate(R.id.action_mainFragment_to_viewBalanceFragment);
            }
        });


    }
}

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/nav_host_fragment"
        android:name="androidx.navigation.fragment.NavHostFragment"
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"

        app:defaultNavHost="true"
        app:navGraph="@navigation/nav_graph" />

</androidx.constraintlayout.widget.ConstraintLayout>

2 个答案:

答案 0 :(得分:1)

您的视图尚未以onCreateView方法附加到您的片段,这就是为什么会出现异常的原因。另一方面,在onViewCreated视图中,片段已附加,您可以使用它。同样,在片段中,您应该仍然可以使用不带参数的findNavController(),但是,如果在视图创建之前对其进行了调用,这也会失败。

答案 1 :(得分:0)

在导航组件中,您需要像这样在主机活动中初始化导航控制器:

   setSupportActionBar(topBarLayout)
    supportActionBar!!.setDisplayHomeAsUpEnabled(false)
    val navHostFragment =
        supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as 
     NavHostFragment
    val navController = navHostFragment.navController
    setupActionBarWithNavController(navController)
    bottomNavigationLayout.setupWithNavController(navController)