Open In App

View Binding with Fragments in Android Jetpack

In the Previous article View Binding in Android Jetpack, it’s been discussed why acquiring the ViewBinding feature in the Android project provides a lot of benefits. But when it comes to ViewBinding with fragments the scenario changes. Because the lifecycle of the Fragment is different and that of activity is different Here also things go the same as discussed in the above article the naming conventions of the fragment layout are changed to pascal case and properties of the fragment layout to camel case. For Example, fragment1.xml -> Fragment1Binding and edit_text(id) which is under the fragment’s layout changes to eEditText(camel case) So in this article ViewBinding is discussed using Fragments. A sample video is given below to get an idea about what we are going to do in this article. Note that we are going to implement this project using the Kotlin language. 

Step by Step Implementation

Step 1: Create a new empty activity project



Step 2: Enable the ViewBinding feature

buildFeatures {



       viewBinding = true

}

Step 3: Working with the activity_main.xml file




<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity"
    tools:ignore="HardcodedText"
    tools:viewBindingIgnore="true">
  
    <Button
        android:id="@+id/fragment_1B"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="16dp"
        android:text="FRAGMENT 1"
        app:layout_constraintEnd_toStartOf="@+id/fragment_2B"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
  
    <Button
        android:id="@+id/fragment_2B"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="16dp"
        android:text="FRAGMENT 2"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintStart_toEndOf="@+id/fragment_1B"
        app:layout_constraintTop_toTopOf="parent" />
  
    <androidx.cardview.widget.CardView
        android:id="@+id/card_view"
        android:layout_width="match_parent"
        android:layout_height="256dp"
        android:layout_marginStart="16dp"
        android:layout_marginTop="16dp"
        android:layout_marginEnd="16dp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/fragment_1B">
  
        <FrameLayout
            android:id="@+id/fragment_holder"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginStart="8dp"
            android:layout_marginEnd="8dp" />
  
    </androidx.cardview.widget.CardView>
  
    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginStart="16dp"
        android:layout_marginTop="16dp"
        android:layout_marginEnd="16dp"
        android:text="SUBMIT"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/card_view" />
  
</androidx.constraintlayout.widget.ConstraintLayout>

Output UI:

Step 4: Creating two fragments




<?xml version="1.0" encoding="utf-8"?>
<!--fragment 1-->
<LinearLayout 
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".ExampleFragment1"
    tools:ignore="HardcodedText">
  
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="16dp"
        android:layout_marginTop="16dp"
        android:text="Fragment 1"
        android:textSize="18sp" />
  
    <EditText
        android:id="@+id/edit_text1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginStart="16dp"
        android:layout_marginTop="16dp"
        android:layout_marginEnd="16dp"
        android:hint="Enter Something" />
  
    <Button
        android:id="@+id/done_button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="end"
        android:layout_marginTop="8dp"
        android:layout_marginEnd="16dp"
        android:text="DONE" />
  
</LinearLayout>




<?xml version="1.0" encoding="utf-8"?>
<!--fragment 2-->
<LinearLayout 
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".ExampleFragment2"
    tools:ignore="HardcodedText">
  
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="16dp"
        android:layout_marginTop="16dp"
        android:text="Fragment 2"
        android:textSize="18sp" />
  
    <EditText
        android:id="@+id/edit_text2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginStart="16dp"
        android:layout_marginTop="16dp"
        android:layout_marginEnd="16dp"
        android:hint="Enter Something" />
  
    <Button
        android:id="@+id/done_button2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="end"
        android:layout_marginTop="8dp"
        android:layout_marginEnd="16dp"
        android:text="DONE" />
  
</LinearLayout>

Step 5: Working with the Fragments.kt files




import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Button
import android.widget.Toast
import androidx.fragment.app.Fragment
  
// Enter your package name here
import com.adityamshidlyali.gfgarticle.databinding.Fragment1Binding
  
class ExampleFragment1 : Fragment() {
  
    // assign the _binding variable initially to null and
    // also when the view is destroyed again it has to be set to null
    private var _binding: Fragment1Binding? = null
  
    // with the backing property of the kotlin we extract
    // the non null value of the _binding
    private val binding get() = _binding!!
  
    override fun onCreateView(
            inflater: LayoutInflater, container: ViewGroup?,
            savedInstanceState: Bundle?
    ): View {
  
        // inflate the layout and bind to the _binding
        _binding = Fragment1Binding.inflate(inflater, container, false)
  
        // retrieve the entered data by the user
        binding.doneButton1.setOnClickListener {
            val str: String = binding.editText1.text.toString()
            if (str.isNotEmpty()) {
                Toast.makeText(activity, str, Toast.LENGTH_SHORT).show()
            } else {
                Toast.makeText(activity, "Please Enter Data", Toast.LENGTH_SHORT).show()
            }
        }
  
        // handle the button from the host activity using findViewById method
        val submitButton: Button = activity!!.findViewById(R.id.submit_button)
        submitButton.setOnClickListener {
            Toast.makeText(activity, "Host Activity Element Clicked from Fragment 1", Toast.LENGTH_SHORT).show()
        }
  
        // Inflate the layout for this fragment
        return binding.root
    }
  
    override fun onDestroyView() {
        super.onDestroyView()
        _binding = null
    }
}




import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Button
import android.widget.Toast
import androidx.fragment.app.Fragment
  
// Enter your package name here
import com.adityamshidlyali.gfgarticle.databinding.Fragment2Binding
  
class ExampleFragment2 : Fragment() {
  
    // assign the _binding variable initially to null and
    // also when the view is destroyed again it has to be 
    // set to null
    private var _binding: Fragment2Binding? = null
  
    // with the backing property of the kotlin
    // we extract
    // the non null value of the _binding
    private val binding get() = _binding!!
  
    override fun onCreateView(
            inflater: LayoutInflater, container: ViewGroup?,
            savedInstanceState: Bundle?
    ): View {
  
        // inflate the layout and bind to the _binding
        _binding = Fragment2Binding.inflate(inflater, container, false)
  
        // retrieve the entered data by the user
        binding.doneButton2.setOnClickListener {
            val str: String = binding.editText2.text.toString()
            if (str.isNotEmpty()) {
                Toast.makeText(activity, str, Toast.LENGTH_SHORT).show()
            } else {
                Toast.makeText(activity, "Please Enter Data", Toast.LENGTH_SHORT).show()
            }
        }
  
        // handle the button from the host activity using findViewById method
        val submitButton: Button = activity!!.findViewById(R.id.submit_button)
        submitButton.setOnClickListener {
            Toast.makeText(activity, "Host Activity Element Clicked from Fragment 2", Toast.LENGTH_SHORT).show()
        }
  
        // Inflate the layout for this fragment
        return binding.root
    }
  
    override fun onDestroyView() {
        super.onDestroyView()
        _binding = null
    }
}

Step 6: Working with the MainActivity.kt file




import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.fragment.app.Fragment
import com.adityamshidlyali.gfgarticle.databinding.ActivityMainBinding
  
class MainActivity : AppCompatActivity() {
  
    // create binding instance for the activity_main.xml
    private lateinit var binding: ActivityMainBinding
  
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)
  
        // when app is initially opened the Fragment 1 should be visible
        supportFragmentManager.beginTransaction().apply {
            replace(binding.fragmentHolder.id, ExampleFragment1())
            addToBackStack(null)
            commit()
        }
  
        // handle the fragment 2 button to toggle the fragment 2
        binding.fragment1B.setOnClickListener {
            changeFragment(ExampleFragment1())
        }
  
        // handle the fragment 2 button to toggle the fragment 2
        binding.fragment2B.setOnClickListener {
            changeFragment(ExampleFragment1())
        }
    }
  
    // function to change the fragment which is used to reduce the lines of code
    private fun changeFragment(fragmentToChange: Fragment): Unit {
        supportFragmentManager.beginTransaction().apply {
            replace(binding.fragmentHolder.id, fragmentToChange)
            addToBackStack(null)
            commit()
        }
    }
}

Output:


Article Tags :