skip to Main Content

i want to transfer data from activity to fragment but i get "Error inflating class fragment" I have searched for solution for that problem but still can’t.

this is my full code of FirstFragment.kt

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.fragment.app.Fragment

// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private const val ARG_PARAM1 = "param1"
private const val ARG_PARAM2 = "param2"

/**
 * A simple [Fragment] subclass.
 * Use the [FirstFragment.newInstance] factory method to
 * create an instance of this fragment.
 */
class FirstFragment : Fragment() {
    // TODO: Rename and change types of parameters
    private var param1: String? = null
    private var param2: String? = null
    private lateinit var communicator: Communicator
    private lateinit var myTextView: TextView

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        arguments?.let {
            param1 = it.getString(ARG_PARAM1)
            param2 = it.getString(ARG_PARAM2)
        }
    }

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        // Inflate the layout for this fragment
        val view = inflater.inflate(R.layout.fragment_first, container, false)
        myTextView = view.findViewById<View>(R.id.profile_name_text) as TextView

        // Gets the data from the passed bundle
        val bundle = arguments
        val message = bundle!!.getString("mText")

        // Sets the derived data (type String) in the TextView
        myTextView.text = message
        return view
    }

    companion object {
        /**
         * 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 FirstFragment.
         */
        // TODO: Rename and change types and number of parameters
        @JvmStatic
        fun newInstance(param1: String, param2: String) =
            FirstFragment().apply {
                arguments = Bundle().apply {
                    putString(ARG_PARAM1, param1)
                    putString(ARG_PARAM2, param2)
                }
            }
    }
}

my function at Home.kt

fun getData() {
    val mFragmentManager = supportFragmentManager
    val mFragmentTransaction = mFragmentManager.beginTransaction()
    val mFragment = FirstFragment()
    val mBundle = Bundle()
    val testText = "My Name is Jack"
    mBundle.putString("mText",testText)
    mFragment.arguments = mBundle
    mFragmentTransaction.add(R.id.fragmentContainerView, mFragment).commit()
}

at the fragment_first.xml i want to put the text into the TextView

<?xml version="1.0" encoding="utf-8"?>
<ScrollView 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=".Home">
<androidx.constraintlayout.widget.ConstraintLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <LinearLayout
        android:id="@+id/linear_Layout_home_1"
        android:layout_width="match_parent"
        android:layout_height="60dp"
        android:layout_marginTop="30dp"
        android:layout_marginStart="15dp"
        android:layout_marginEnd="15dp"
        android:paddingStart="15dp"
        android:paddingEnd="15dp"
        android:paddingTop="10dp"
        android:orientation="horizontal"
        android:background="@drawable/rounded_blue_shape"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="parent">


            <TextView
                android:id="@+id/profile_name_text"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="@string/nama_pengguna"
                android:textStyle="bold"
                android:textSize="15sp"
                android:textColor="@color/cloudy"/>
    </LinearLayout>

</androidx.constraintlayout.widget.ConstraintLayout>
</ScrollView>

this is code of activity_home.xml

<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=".Home">

        <com.google.android.material.bottomnavigation.BottomNavigationView
            android:id="@+id/bottom_navigation"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:menu="@menu/navigation"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintBottom_toBottomOf="parent"/>


    <fragment
        android:id="@+id/fragmentContainerView"
        android:name="androidx.navigation.fragment.NavHostFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:defaultNavHost="true"
        app:navGraph="@navigation/my_nav"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"/>

</androidx.constraintlayout.widget.ConstraintLayout>

Can anybody help me please?

3

Answers


  1. You can pass the data using fragment constructor like this:

    fun getData() {
    
       val mFragmentManager = supportFragmentManager
       val mFragmentTransaction = mFragmentManager.beginTransaction()
       val testText = "My Name is Jack"
       val mFragment = FirstFragment(testText)
       mFragmentTransaction.add(R.id.fragmentContainerView, mFragment).commit()
    }
    

    And fetch it in the fragment like this:

    class FirstFragment(private val someText: String): Fragment() {
    
        private lateinit var myTextView: TextView
    
        override fun onCreateView(
            inflater: LayoutInflater, container: ViewGroup?,
            savedInstanceState: Bundle?
        ): View? {
            // Inflate the layout for this fragment
            val view = inflater.inflate(R.layout.fragment_first, container, false)
            myTextView = view.findViewById<View>(R.id.profile_name_text) as TextView
    
            // Sets the derived data (type String) in the TextView
            myTextView.text = someText
            return view
        }
    }
    

    Also seeing your fragment_first.xml layout, you might wanna put it like this:

    <RelativeLayout 
        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">
    
            <TextView
                android:id="@+id/profile_name_text"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="@string/nama_pengguna"
                android:textStyle="bold"
                android:textSize="15sp"
                android:textColor="@color/cloudy"/>
    
    </RelativeLayout>
    
    Login or Signup to reply.
  2. Not sure what caused your issue. But noticed you are using Jetpack navigation.

    And you’re trying to pass data to the start destination of the graph.

    Here is an official doc for dealing with your case:
    Pass data to the start destination.

    And below are some of the code I tried myself, just for your reference:

    I think in your MainActivity.kt, you would have something like this:

            val navController = findNavController(R.id.fragmentContainerView)
            navController.setGraph(R.navigation.my_nav, Bundle().apply {
                putString("name", "My name is xx")
            })
    

    And in the first fragment, retrieve the parameter:

        override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
            super.onViewCreated(view, savedInstanceState)
    
            val name = arguments?.get("name")
            Log.w("xx", "$name")
    

    Edit: I updated the findNavController(R.id.fragmentContainerView) and navController.setGraph(R.navigation.my_nav according to the ids in your code.

    Login or Signup to reply.
  3. Base on documentation:

    Note: when manually calling setGraph() with arguments, you must not use the app:navGraph attribute when creating the NavHostFragment in XML as that will internally call setGraph() without any arguments, resulting in your graph and start destination being created twice.

    docs

    You’ve already defined app: navGraph on your activity(Fragment Container) so you can’t call navController. SetGraph from java/kotlin.
    Try with remove app:navGraph from Fragment Container

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search