Search code examples
androidkotlinandroid-activityfragmentcommunication

On click of the Button I want Fragment 1 layout to be replaced with Fragment 2 layout but its throwing: java.lang.NullPointerException


First Fragment's code

class MainFragment : Fragment() {

override fun onCreateView(
    inflater: LayoutInflater, container: ViewGroup?,
    savedInstanceState: Bundle?
): View? {
    // Inflate the layout for this fragment
    val mainInflater = inflater.inflate(R.layout.fragment_main, container, false)
    return mainInflater
}

fun thisdata():String{

    return "Hello from MainFragment"
}

}

First Fragment XML

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainFragment">

    <EditText
        android:id="@+id/etSavedData"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="60dp"
        android:hint="Enter the Text"/>

    <Button
        android:id="@+id/btnSaveData"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="120dp"
        android:text="Save"/>

</RelativeLayout>

Main Activity's code

class MainActivity : AppCompatActivity() {

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    //Set replace Main Activity content with the Fragment1 content
    val mainFragment = MainFragment()

    supportFragmentManager.beginTransaction().add(R.id.contain_fragment, mainFragment).commit()
    val thedata = mainFragment.thisdata()
    Log.e("Main Frag to Activity", thedata)

    btnSaveData.setOnClickListener { 

        val secondFragment = SecondFragment()
        supportFragmentManager.beginTransaction().add(R.id.contain_fragment, secondFragment).commit()
    }

}

}

Main Activity XML

<?xml version="1.0" encoding="utf-8"?>
<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"
    android:id="@+id/contain_fragment"
    tools:context=".MainActivity">


</RelativeLayout>

Second Fragment's code

class SecondFragment : Fragment() {

override fun onCreateView(
    inflater: LayoutInflater, container: ViewGroup?,
    savedInstanceState: Bundle?
): View? {
    // Inflate the layout for this fragment
    val secondInflater = inflater.inflate(R.layout.fragment_second, container, false)
    return secondInflater
}

}

Second Fragment XML

    <?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@android:color/holo_blue_dark"
    tools:context=".SecondFragment">

    <!-- TODO: Update blank fragment layout -->
    <TextView
        android:id="@+id/tvDisplayText"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        tools:text="Text displayed here." />

</FrameLayout>

Following Exception showing up in Logcat

Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.Button.setOnClickListener(android.view.View$OnClickListener)' on a null object reference at com.example.demo2.MainActivity.onCreate(MainActivity.kt:22)*


Solution

  • **Thanks Tash, that actually make sense, unfortunately it was still showing the same exception but I finally manage to resolve the issue by doing the following. **

        class MainFragment : Fragment() {
    
        override fun onCreateView(
            inflater: LayoutInflater, container: ViewGroup?,
            savedInstanceState: Bundle?
        ): View? {
            // Inflate the layout for this fragment
            val mainInflater = inflater.inflate(R.layout.fragment_main, container, false)
             mainInflater.btnSaveData.setOnClickListener {
    
            val secondFragment = SecondFragment()
    
                secondFragment?.let {
                     activity?.supportFragmentManager?.beginTransaction()?.replace(R.id.contain_fragment, secondFragment)?.commit()
                 }
    
                }
            return mainInflater
        }
    
        fun thisdata():String{
    
            return "Hello from MainFragment"
        }
    
    }