I just started to use the Jetpack Navigation components and SafeArgs for navigation in Android. However, I do not understand how I can navigate from one destination to another one (I read the google documentation but this was confusing for me). So I have a Menu_Fragment class that has a link in the NavGraph to a Softdrink class. A Menu_FragmentDirections class was automatically created. However, I do not know how to use it within the Menu_Fragment class to implement an OnClick listener event. Here I have the onClick method in the Menu_Fragment class (see https://developer.android.com/guide/navigation/navigation-navigate):
@Override
public void onClick(View view) {
if(view.getId() == R.id.imageButton_Softdrinks_en) {
float amount = ...;
action =
Menu_FragmentDirections
.actionMenuFragmentToSoftdrinks(amount);
Navigation.findNavController(view).navigate(action);
}
}
Here you can see the Menu_FragmentDirections class:
package com.example.td.barapp;
import androidx.annotation.NonNull;
import androidx.navigation.ActionOnlyNavDirections;
import androidx.navigation.NavDirections;
public class Menu_FragmentDirections {
private Menu_FragmentDirections() {
}
@NonNull
public static NavDirections actionMenuFragmentToSoftdrinks() {
return new ActionOnlyNavDirections(R.id.action_menu_Fragment_to_softdrinks);
}
}
And here you can see the NavGraph:
<?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/nav_graph"
app:startDestination="@id/menu_Fragment">
<fragment
android:id="@+id/menu_Fragment"
android:name="com.example.td.barapp.Menu_Fragment"
android:label="fragment_menu_"
tools:layout="@layout/fragment_menu" >
<action
android:id="@+id/action_menu_Fragment_to_softdrinks"
app:destination="@id/softdrinks" />
</fragment>
<fragment
android:id="@+id/softdrinks"
android:name="com.example.td.barapp.Softdrinks"
android:label="fragment_softdrinks"
tools:layout="@layout/fragment_softdrinks" />
</navigation>
Can anybody tell me, what I have to do in the onCreateMethod() posted above.I get the error messages: "Cannot resolve symbol 'action'" and "Cannot resolve symbol 'Navigation'" (and of course the error for using the unexpected token '...')
I'd appreciate every comment and would be quite thankful for your help.
Update here is the complete Menu_Fragment class with the onCreateMethod:
package com.example.td.barapp;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import com.example.td.barapp.databinding.FragmentMenuBinding;
/**
* A simple {@link Fragment} subclass.
* Use the {@link Menu_Fragment#newInstance} factory method to
* create an instance of this fragment.
*/
public class Menu_Fragment extends Fragment implements View.OnClickListener {
// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";
// TODO: Rename and change types of parameters
private String mParam1;
private String mParam2;
private Menu_Fragment() {
// Required empty public constructor
}
/**
* Use this factory method to create a new instance of
* this fragment using the provided parameters.
*
* @param param1 Parameter 1.
* @param param2 Parameter 2.
* @return A new instance of fragment Menu_Fragment.
*/
// TODO: Rename and change types and number of parameters
public static Menu_Fragment newInstance(String param1, String param2) {
Menu_Fragment fragment = new Menu_Fragment();
Bundle args = new Bundle();
args.putString(ARG_PARAM1, param1);
args.putString(ARG_PARAM2, param2);
fragment.setArguments(args);
return fragment;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mParam1 = getArguments().getString(ARG_PARAM1);
mParam2 = getArguments().getString(ARG_PARAM2);
}
}
private FragmentMenuBinding binding;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
binding = FragmentMenuBinding.inflate(inflater, container, false);
return binding.getRoot();
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
binding.imageButtonCocktailsEn.setOnClickListener(this);
binding.imageButtonCocktailsAlcfreeEn.setOnClickListener(this);
binding.imageButtonLongdrinksEn.setOnClickListener(this);
binding.imageButtonWhiskyEn.setOnClickListener(this);
binding.imageButtonLiquorEn.setOnClickListener(this);
binding.imageButtonBeerEn.setOnClickListener(this);
binding.imageButtonSoftdrinksEn.setOnClickListener(this);
binding.imageButtonHotDrinksEn.setOnClickListener(this);
}
public void onDestroyView() {
super.onDestroyView();
binding = null;
}
@Override
public void onClick(View view) {
if(view.getId() == R.id.imageButton_Softdrinks_en) {
float amount = 0f;
Menu_FragmentDirections.ActionMenuFragmentToSoftdrinks action = Menu_FragmentDirections
.actionMenuFragmentToSoftdrinks(amount);
}
}
}
You are missing the object type before the action.
It would like like this:
Menu_FragmentDirections.ActionMenuFragmentToSoftdrinks action = Menu_FragmentDirections
.actionMenuFragmentToSoftdrinks(amount);
And the error:
error: illegal start of expression float amount = ...;
It's because you want a float and you are passing "...". It must be a floating number.
Ie:float amount = 0.6f
or float amount = 0f
.
EDIT:
To add an argument to a fragment, please do the following steps:
Select the destination fragment and click on the plus as highlighted.
After that, choose the type of variable you want and give it a name
Rebuild your project and check it if it's now working.
Hope it helped.