visit
Fragments cannot live on their own-they must be hosted by activity or another fragment. The Fragment also has its life cycle:
Let’s create Fragment. To do this, we need to create layout files for them and classes with an ancestor androidx.fragment.app.Fragment
fragment1.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="//schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#77ff0000"
android:orientation="vertical">
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Fragment 1">
</TextView>
</LinearLayout>
Fragment1.kt:
class Fragment1: Fragment() {
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
Log.e(TAG, "onCreateView: ")
return inflater.inflate(R.layout.fragment1, container, false)
}
}
For interaction between fragments, the androidx.fragment.app.FragmentManager
class is used - a special fragment manager.
Before starting a transaction, you need to get an instance of FragmentTransaction via the FragmentManager.beginTransaction() method. Next, various methods are called to manage the fragments.
At the end of any transaction, which may consist of a chain of the above methods, the commit() method should be called.
val fragmentManager = supportFragmentManager
fragmentManager.beginTransaction()
.remove(fragment1)
.add(R.id.fragment_container, fragment2)
.show(fragment3)
.hide(fragment4)
.commit()
add()
Adds a fragment to an activity
remove() Removes a fragment from an activity
replace() Replaces one fragment with another
hide() Hides the fragment (makes it invisible on the screen)
show() Displays a hidden fragment on the screen
detach() (API 13) Detaches the fragment from the GUI, but the class instance is retained
attach() (API 13) Attaches a fragment that has been detached by the detach() method
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val fragmentManager = supportFragmentManager
fragmentManager.beginTransaction()
.add(R.id.fragment_container, Fragment1())
.commit()
}
}
A fragment must have only one empty constructor with no arguments. But you can create a static newInstance with arguments via the setArguments() method.
class Fragment1 : Fragment() {
...
companion object {
private const val KEY = "VALUE_KEY"
fun newInstance(value: String) = Fragment1().apply {
arguments = Bundle().apply {
putString(KEY, value)
}
}
}
}
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val fragmentManager = supportFragmentManager
fragmentManager.beginTransaction()
.replace(R.id.fragment_container, Fragment1.newInstance("some text "))
.commit()
}
}
The arguments can be accessed in the onCreate() method of the fragment:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val text = requireArguments().getString(KEY, "")
}
Fragments, like activities, can be controlled by the Back button. You can add several fragments, and then use the Back button to return to the first fragment. If no fragments remain on the stack, then the next button press will close the activity.
To add a transaction to the stack, call the FragmentTransaction.addToBackStack(String) method before committing the transaction. The string argument is an optional name to identify the stack, or null. The FragmentManager class has a popBackStack() method that returns the previous stack state by that name.
val fragmentManager = supportFragmentManager
fragmentManager.beginTransaction()
.replace(R.id.fragment_container, Fragment1.newInstance("some text "))
.addToBackStack(null)
.commit()
If you call the addToBackStack() method when removing or replacing a fragment, then the fragment methods onPause(), onStop(), onDestroyView() will be called.
When the user presses the back button, the fragment methods onCreateView(), onActivityCreated(), onStart() and onResume() are called.
Let's consider an example of reacting to the Back button in a fragment without using the stack. The activity has an onBackPressed() method that responds to the button being pressed. We can refer to the desired fragment in this method and call it the fragment method.