# Fragment Communication

**Activity can send data to Fragment and receive data from Fragment**

All Fragment-to-Fragment communication is done through host Activity

<div align="left"><img src="https://lh4.googleusercontent.com/Bl0CzdHnkEEGiNjopgyifIWnkVjIQ69nv-6Mq1h56nfg01UEQoEMGzcG_3S-s7uhFUlWlDwQL-FD0dTeZJeqwqeQaOPnEDNvJWD_-BMGP6-uEYGQkYmvZMTb7PKif8VPeWTe8sJz1xk" alt=""></div>

### `RatingFragment`Setup

Add a  `String`variable and `float` value, we will be using this to place inside the `Bundle`

```java
private static final String CHOICE="choice";
public float choice;
```

&#x20;Define a listener interface called `OnFragmentInteractionListener`. In it, specify a callback method that you will create, called `onRadioButtonChoice()`:

```java
interface OnFragmentInteractionListener {
    void onRatingChoice(int choice);
}
```

Add a variable for the listener later

```java
OnFragmentInteractionListener mListener;
```

&#x20;Override the [`onAttach()`](https://developer.android.com/reference/android/app/Fragment.html#onAttach\(android.app.Activity\)) lifecycle method in `SimpleFragment` to capture the host `Activity` interface implementation:

```java
@Override
public void onAttach(Context context) {
    super.onAttach(context);
    if (context instanceof OnFragmentInteractionListener) {
        mListener = (OnFragmentInteractionListener) context;
    } else {
        throw new ClassCastException(context.toString()
           + getResources().getString(R.string.exception_message));
    }
}
```

The `onAttach()` method is called as soon as the `Fragment` is associated with the `Activity`. The code makes sure that the host `Activity` has implemented the callback interface. If not, it throws an exception.

{% hint style="info" %}
The string resource `exception_message` is included in the **source code** for the text `"must implement OnFragmentInteractionListener"`
{% endhint %}

Overall, your class should end up looking like this.

```java
public class RatingFragment extends Fragment {
    private static final String CHOICE="choice";
    public float choice;
    OnFragmentInteractionListener mListener;

    interface OnFragmentInteractionListener {
        void onRatingChoice(float choice);
    }

    public RatingFragment() {
        // Required empty public constructor

    }

    public static RatingFragment newInstance(float choice) {
        RatingFragment fragment = new RatingFragment();
        Bundle arguments = new Bundle();
        arguments.putFloat(CHOICE, choice);
        fragment.setArguments(arguments);
        return fragment;
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        final View rootView = inflater.inflate(R.layout.fragment_rating, container, false);
        final RatingBar rB = rootView.findViewById(R.id.ratingBar);
        if (getArguments().containsKey(CHOICE)) {
            // A choice was made, so get the choice.
            choice = getArguments().getFloat(CHOICE);
            // Check the radio button choice.
            if (choice!=0) {
                rB.setRating(choice);
            }
        }

        rB.setOnRatingBarChangeListener(new RatingBar.OnRatingBarChangeListener() {
            @Override
            public void onRatingChanged(RatingBar ratingBar, float v, boolean b) {
                String s = getString(R.string.rating_message);
                choice = v;
                mListener.onRatingChoice(v);
                //Toast.makeText(getActivity().getApplicationContext(),s+ " "+ v,Toast.LENGTH_SHORT).show();
            }
        });
        return rootView;
    }
    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        if (context instanceof OnFragmentInteractionListener) {
            mListener = (OnFragmentInteractionListener) context;
        } else {
            throw new ClassCastException(context.toString()
                    + getResources().getString(R.string.exception_message));
        }
    }

}

```

### Implementing `OnFragmentInteractionListener`

Now that we have set up our `RatingListener` for communication. We need to implement the `OnFragmentInteractionListener` in the activity in order to receive data from fragment

```java
public class MainActivity extends AppCompatActivity
        implements RatingFragment.OnFragmentInteractionListener {
```

Add  a member variable in `MainActivity` for the choice the user makes with the `RatingBar`, and set it to the default value

```java
private float mRatingChoice = 0; // The default (no choice).
static final String STATE_CHOICE = "user_choice";
```

```java
@Override
    public void onRatingChoice(float choice) {
        mRatingChoice = choice;
        Toast.makeText(this,"Choice is "+ Float.toString(choice),Toast.LENGTH_SHORT).show();
}
```

Set up the `onSaveInstanceState(Bundle)` to save our float variable and states for the `Activity`

```java
@Override
public void onSaveInstanceState(Bundle savedInstanceState){
        savedInstanceState.putBoolean(STATE_FRAGMENT,isFragmentDisplayed);
        savedInstanceState.putFloat(STATE_CHOICE, mRatingChoice);
        super.onSaveInstanceState(savedInstanceState);
    }
```

The app should now show a toast when you click it.

### Providing user's choice to fragment (Main

&#x20;We have to now set a [`Bundle`](https://developer.android.com/reference/android/os/Bundle.html) and use the `Fragment.`[`setArguments(Bundle)`](https://developer.android.com/reference/android/app/Fragment.html#setArguments\(android.os.Bundle\)) method to supply the construction arguments for the `Fragment`.

A Bundle is like a key-value dictionary which allows to transfer information to other activities, fragments.

First, let's setup a `newInstance()` method to use a `Bundle` and `setArguments`

```java
 public static RatingFragment newInstance(float choice) {
        RatingFragment fragment = new RatingFragment();
        Bundle arguments = new Bundle();
        arguments.putFloat(CHOICE, choice);
        fragment.setArguments(arguments);
        return fragment;
    }
```

Add following code to `onCreateView()` method to retrieve the previously set value of choice

```java
if (getArguments().containsKey(CHOICE)) {
            // A choice was made, so get the choice.
            choice = getArguments().getFloat(CHOICE);
            // Check the radio button choice.
            if (choice!=0) {
                rB.setRating(choice);
            }
        }
```

Lastly, we need to change our functions in `MainActivity` to `RatingFragment.newInstance(mRatingChoice);`

```java
public void displayFragment(){
        RatingFragment ratingFragment = RatingFragment.newInstance(mRatingChoice);
        FragmentManager fragmentManager = getSupportFragmentManager();
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
        fragmentTransaction.add(R.id.fragment_container,ratingFragment).addToBackStack(null).commit();
        sButtonl.setText(R.string.button_carClose);
        isFragmentDisplayed = true;
    }
    public void closeFragment(){
        FragmentManager fragmentManager = getSupportFragmentManager();
        RatingFragment ratingFragment = (RatingFragment)fragmentManager.findFragmentById(R.id.fragment_container);
        if(ratingFragment!=null){
            FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
            fragmentTransaction.remove(ratingFragment).addToBackStack(null).commit();
        }
        sButtonl.setText(R.string.button_car);
        isFragmentDisplayed = false;

    }
```

Your app should be communicating the choice from the `Fragment` to the `Activity`, and then back to the `Fragment`which should display the choice you made previously always

#### End Result:

```java
public class MainActivity extends AppCompatActivity implements RatingFragment.OnFragmentInteractionListener{
    Button sButtonl;
    private Boolean isFragmentDisplayed = false;
    static final String STATE_FRAGMENT = "state_of_fragment";
    private float mRatingChoice = 0;
    static final String STATE_CHOICE = "user_choice";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        sButtonl = findViewById(R.id.button);
        sButtonl.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if(!isFragmentDisplayed){
                    displayFragment();
                }else{
                    closeFragment();
                }
            }
        });
        if(savedInstanceState!=null){
            isFragmentDisplayed = savedInstanceState.getBoolean(STATE_FRAGMENT);
            mRatingChoice = savedInstanceState.getInt(STATE_CHOICE);
        }

    }
    @Override
    public void onSaveInstanceState(Bundle savedInstanceState){
        savedInstanceState.putBoolean(STATE_FRAGMENT,isFragmentDisplayed);
        savedInstanceState.putFloat(STATE_CHOICE, mRatingChoice);
        super.onSaveInstanceState(savedInstanceState);
    }
    public void displayFragment(){
        RatingFragment ratingFragment = RatingFragment.newInstance(mRatingChoice);
        FragmentManager fragmentManager = getSupportFragmentManager();
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
        fragmentTransaction.add(R.id.fragment_container,ratingFragment).addToBackStack(null).commit();
        sButtonl.setText(R.string.button_carClose);
        isFragmentDisplayed = true;
    }
    public void closeFragment(){
        FragmentManager fragmentManager = getSupportFragmentManager();
        RatingFragment ratingFragment = (RatingFragment)fragmentManager.findFragmentById(R.id.fragment_container);
        if(ratingFragment!=null){
            FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
            fragmentTransaction.remove(ratingFragment).addToBackStack(null).commit();
        }
        sButtonl.setText(R.string.button_car);
        isFragmentDisplayed = false;

    }


    @Override
    public void onRatingChoice(float choice) {
        mRatingChoice = choice;
        Toast.makeText(this,"Choice is "+ Float.toString(choice),Toast.LENGTH_SHORT).show();
    }
}
```

From this point, there are more complicated paths and communications you can perform, but these steps lay a foundation in using them.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://kaleb-is-caleb.gitbook.io/infosys/fragments/fragment-communication.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
