0

I have a Fragment A containing a Fragment B.

I want to pass an argument to Fragment B from Fragment A when Fragment A is in the onActivityCreated lifecycle (because I have a data coming from a viewmodel that arrives at this moment).

In my Fragment B I cannot get the argument. I have a null exception.

Do you have a solution to my problem?

Here is my code

Fragment A

class FragmentA: Fragment() {

    private lateinit var fragmentB: FragmentB

    /**
     * @inheritdocs
     */
    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
                              savedInstanceState: Bundle?): View? {
        return inflater.inflate(R.layout.fragment_a, container, false)
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        this.fragmentB = FragmentB()
        val transaction = childFragmentManager.beginTransaction()
        transaction.add(R.id.fragmentB, fragmentB).commit()
    }

    /**
     * @inheritdocs
     */
    override fun onActivityCreated(savedInstanceState: Bundle?) {
        super.onActivityCreated(savedInstanceState)

        val args = Bundle()
        args.putString("name", "test")
        this.fragmentB.arguments = args
    }
}

FragmentB

class FragmentB: Fragment() {


    /**
     * @inheritdocs
     */
    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
                              savedInstanceState: Bundle?): View? {
        return inflater.inflate(R.layout.fragment_b, container, false)
    }

    /**
     * @inheritdocs
     */
    override fun onActivityCreated(savedInstanceState: Bundle?) {
        super.onActivityCreated(savedInstanceState)

        var name = this.arguments?.getString("name")!!
    }
}

fragment_a.xml

<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <fragment
        android:id="@+id/fragmentB"
        android:name="com.test.view.FragmentB"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"/>

</androidx.constraintlayout.widget.ConstraintLayout>
Dev Loots
  • 708
  • 9
  • 28

3 Answers3

2

You have declared Fragment in your xml layout. This means it gets created without the args. If you are adding Fragment from code, then you don't need to declare it in xml.

So just change your xml to this:

<androidx.constraintlayout.widget.ConstraintLayout       
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <FrameLayout
        android:id="@+id/fragmentB"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"/>

</androidx.constraintlayout.widget.ConstraintLayout>
vilpe89
  • 4,656
  • 1
  • 29
  • 36
1

Inside your fragment B implement static method to initialize the fragment like bellow.

public static FragmentB newInstance(string x) {
  FragmentB f = new FragmentB ();

  Bundle args = new Bundle();
  args.putInt("name", x);
  f.setArguments(args);
  return f;
}

you can use this method in FragmentA

Read more in here

Eranga Gamagedara
  • 536
  • 1
  • 3
  • 10
0

If you have your data in a viewmodel there is no reason the fragment itself cannot access this directly. One of the pluses of viewmodels is ease of sharing the data of a screen among its constituent components be they views/fragments/whatevers.

You can refer to the documentation here.

macgills
  • 31
  • 7