In my MainFragment class, when trying to initialize NavController in the onCreateView
, I get a RuntimeException caused by:
IllegalStateException: View android.widget.RelativeLayout{cf3c6de V.E...... ......I. 0,0-0,0 #7f0800d7 app:id/parentLayout} does not have a NavController set
.
If the NavController is initialised in the onViewCreated
method, it will work just fine. Why is that? I couldn't figure it out from the tutorials / documentation.
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 ,if it is relevant
<?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>
Your view is not yet attached to your fragment in onCreateView
method, thats why you get exception. On the other hand in onViewCreated
view is attached to fragment and you can use it. Also in fragments you should be able to use findNavController()
without arguments, still, this will also fail if its called before view is created.