Android Tips & Traps

Getting the current fragment in ViewPager2 with FragmentStateAdapter

When using a ViewPager2 widget with FragmentStateAdapter, the adapter offers no way to get the current fragment. To illustrate a solution, let's assume there is a TabLayout with a ViewPager2 widget and each page in the ViewPager2 widget uses the same fragment.


<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              xmlns:app="http://schemas.android.com/apk/res-auto"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:orientation="vertical">

    ...

    <com.google.android.material.tabs.TabLayout android:id="@+id/tablayout"
                                                android:layout_width="match_parent"
                                                android:layout_height="wrap_content"
                                                app:tabMode="scrollable" />

    <androidx.viewpager2.widget.ViewPager2 android:id="@+id/pager"
                                           android:layout_width="match_parent"
                                           android:layout_height="0dp"
                                           android:layout_weight="1" />
</LinearLayout>
						 

The screen that loads this layout must be a Fragment.


class GroupViewFragment : Fragment() {
	// A public var that stores the current fragment
	var currentPage: GroupEditFragment? = null
	
	...

	private inner class PagesAdapter : FragmentStateAdapter(this) {
        override fun getItemCount(): Int = 6

        override fun createFragment(position: Int): Fragment {
            return GroupEditFragment().apply {
                arguments = Bundle().also {
                    it.putInt("Type", position + 1)
                }
            }
        }

    }
}						 

In the GroupEditFragment, set currentPage variable in the parent fragment which is GroupViewFragment.


class GroupEditFragment : Fragment() {
	...

    override fun onPause() {
        super.onPause()

	    // Remove the reference to ensure proper resource disposal
        parentFragment?.run {
            (this as GroupViewFragment).currentPage = null
        }
    }

    override fun onResume() {
        super.onResume()

        // Inform the parent fragment about itself
        parentFragment?.run {
            (this as GroupViewFragment).currentPage = this@GroupEditFragment
        }
    }

    ...
}
						 
NumberPicker getValue() method does not return last edited value

When the user edited the value of the NumberPicker using the soft keyboard just before closing the activity, the getValue() method does not return the updated value. To solve this problem, add a call to clearFocus() before calling getValue().