# Creating a Fragment Dynamically

Let's continue from our current activity!

The main difference in creating a fragment is that you have to manage the `Fragment` using [`FragmentManager`](https://developer.android.com/reference/android/app/FragmentManager.html) and [`FragmentTransaction`](https://developer.android.com/reference/android/app/FragmentTransaction.html) statements that can add, remove, and replace a `Fragment`

### Creating a Fragment Class

Just as you did just now,  create a fragment called `RatingFragment` .

### Set the Layout of the Class

This time, let's use a `RatingBar` instead of a `RadioGroup` with `RadioButtons`

```markup
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:tools="http://schemas.android.com/tools"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    android:background="@color/fragment_color"
    tools:context=".RatingFragment">

    <TextView
        android:id="@+id/carText"
        android:layout_marginLeft="@dimen/padding_standard"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textAppearance="@style/TextAppearance.AppCompat.Medium"
        android:padding="4dp"
        android:text="@string/rating_message" />
    <RatingBar
        android:id="@+id/ratingBar"
        style="@android:style/Widget.DeviceDefault.RatingBar.Small"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:numStars="6"
        android:padding="8dp"
        android:rating="0"
        android:stepSize="0.5"
        android:isIndicator="false"
        />

</LinearLayout>
```

Now just as we did before, we can edit and place interactivity in our fragment right away.

In this new fragment, we have a new function `newInstance()`. This allows us to instantiate the `Fragment` in the `MainActivity` later on.

```java
 public static RatingFragment newInstance() {

        RatingFragment fragment = new RatingFragment();
        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);
        rB.setOnRatingBarChangeListener(new RatingBar.OnRatingBarChangeListener() {
            @Override
            public void onRatingChanged(RatingBar ratingBar, float v, boolean b) {
                String s = getString(R.string.rating_message);
                Toast.makeText(getActivity().getApplicationContext(),s+ " "+ v,Toast.LENGTH_SHORT).show();
            }
        });
        return rootView;
    }
```

{% hint style="info" %}
Note:[`Toast`](https://developer.android.com/guide/topics/ui/notifiers/toasts) here displays simple messages in a small popup for a selected amount of time.
{% endhint %}

Great! Now all we need is to edit the rest on the `MainActivity` and `activity_main.xml`

### Creating functions to display/hide Fragments

We are going to use a `<FrameLayout>` as a fragment container instead of a \<fragment> in `activity_main.xml`

First, let's specify [`ViewGroup`](https://developer.android.com/reference/android/view/ViewGroup.html) for `Fragment` in layout

```markup
<FrameLayout
    android:id="@+id/fragment_container"
    android:name="com.example.fragmentdemo1.RatingFragment"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintRight_toRightOf="parent"
    app:layout_constraintTop_toBottomOf="@id/fragment"
    tools:layout="@layout/fragment_rating" />
```

Add the following code within the `MainActivity`class.

```java
    public void displayFragment(){
        RatingFragment ratingFragment = RatingFragment.newInstance();
        FragmentManager fragmentManager = getSupportFragmentManager();
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
        fragmentTransaction.add(R.id.fragment_container,ratingFragment).addToBackStack(null).commit();
        sButtonl.setText(R.string.close);
        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.open);
        isFragmentDisplayed = false;

    }
```

What the code is doing here is instantiating `RatingFragment`and `FragmentManager`&#x20;

Use `getSupportFragmentManager()` for compatibility

Use [`FragmentTransaction`](https://developer.android.com/reference/androidx/fragment/app/FragmentTransaction)  for adding/removing/replacing dynamically.

#### FragmentManager:

`FragmentManager` interacts with Fragment which are within an `Activity`.

| Function                       | What it does                                                 |
| ------------------------------ | ------------------------------------------------------------ |
| **`beginTransaction()`**       | start fragment transaction and returns `FragmentTransaction` |
| **`findFragmentById(int id)`** | by passing id, it returns fragment instance.                 |

#### FragmentTransaction

`FragmentTransaction`performs fragment operations. Find some methods.

| Function                                              | What it does                                                                               |
| ----------------------------------------------------- | ------------------------------------------------------------------------------------------ |
| **`add(int containerViewId, Fragment fragment)`**     | adds a given fragment to activity state.                                                   |
| **`attach(Fragment fragment)`**                       | The detached fragment can be re-attached by using this method.                             |
| **`detach(Fragment fragment)`**                       | Detaches the given fragment from UI. Fragment state is still managed by `FragmentManager`. |
| **`remove(Fragment fragment)`**                       | Removes the given fragment from UI and container.                                          |
| **`replace(int containerViewId, Fragment fragment)`** | For the given container view id, we can replace existing fragment by new given fragment.   |
| **`commit()`**                                        | Transaction is committed.                                                                  |

Fragment operations are wrapped into a transaction:

* Start transaction with [`beginTransaction()`](https://developer.android.com/reference/android/app/FragmentManager.html#beginTransaction\(\))
* Do all Fragment operations (`add`, `remove`, etc.)
* `addingtoBackStack(null)` saves transaction to the back stack so the user can reverse the transaction and bring back the previous fragment by pressing the Back button.
* End transaction with [`commit()`](https://developer.android.com/reference/android/app/FragmentTransaction.html#commit\(\))

Alright, now we just need to add a `Button` and set up its `OnClickListener()` to our functions

First, place the button in the `activity_main.xml` layout

```markup
<Button
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintRight_toRightOf="parent"
    android:id="@+id/button"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/button_car"
    app:layout_constraintTop_toBottomOf="@id/article"
    />
```

Now, find its view in the `MainActivity` and `setOnClickListener()`

```java
Button sButtonl;
    private Boolean isFragmentDisplayed = false;
    static final String STATE_FRAGMENT = "state_of_fragment";

    @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);
        }
        
    }
    @Override
    public void onSaveInstanceState(Bundle savedInstanceState){
        savedInstanceState.putBoolean(STATE_FRAGMENT,isFragmentDisplayed);
        super.onSaveInstanceState(savedInstanceState);
    }
    
```

And you should be able to build and run your app!


---

# 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/untitled-1.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.
