Say you want a generic design in all your Fragments but hate doing it again and again every time you create a new Fragment.
Enter abstract fragments with containers.
Step 1. Create a Base Fragment
abstract class BaseFragment(
private val contentResId: Int = 0
) : Fragment() {
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
super.onCreateView(inflater, container, savedInstanceState)
return inflater.inflate(R.layout.base_container, container, false).also {
val containerContent = it!!.findViewById<FrameLayout>(R.id.container_content)
containerContent.addView(
onCreateContentView(inflater, containerContent, savedInstanceState)
)
}
}
open fun onCreateContentView(
inflater: LayoutInflater,
onboardingContainer: FrameLayout,
savedInstanceState: Bundle?
): View {
return inflater.inflate(contentResId, onboardingContainer, false)
}
}
The interesting part over here is inflating the container and adding the it to the base layout.
This is how the XML would look like
<?xml version="1.0" encoding="utf-8"?>
<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"
android:clipChildren="false"
android:clipToPadding="false"
android:fitsSystemWindows="false">
<FrameLayout
android:id="@+id/container_content"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</ConstraintLayout>
Step 2.
Create a new Fragment and extend from the above base fragment
class DoSomethingFragment(): BaseFragment(R.layout.do_something_xml)
And that's it. You get all the benefits of the BaseFragment, its design, elements, etc and you get the features of the implementing fragment as well. Pretty cool!