title: Android ViewPager2 fragment destroying behavior does not comply with offscreenPageLimit
body: <p>I am using <code>ViewPager2</code> with <code>FragmentStateAdapter</code> and I am setting <code>offscreenPageLimit</code> to <code>1</code>. Each <code>Fragment</code> contains a surface (obtained via a <code>TextureView</code>) to be drawn on.</p>
  <p>The code is fairly simple:</p>
  <pre><code>package com.example.testapplication
  
  import android.annotation.SuppressLint
  import android.content.Context
  import android.graphics.Color
  import android.graphics.SurfaceTexture
  import androidx.appcompat.app.AppCompatActivity
  import android.os.Bundle
  import android.util.Log
  import android.view.*
  import androidx.fragment.app.Fragment
  import androidx.viewpager2.adapter.FragmentStateAdapter
  import androidx.viewpager2.widget.ViewPager2
  import kotlinx.android.synthetic.main.item_fragment.*
  
  class MainActivity : AppCompatActivity() {
  
      override fun onCreate(savedInstanceState: Bundle?) {
          super.onCreate(savedInstanceState)
          setContentView(R.layout.activity_main)
  
          val pageAdapter = object: FragmentStateAdapter(this) {
              override fun createFragment(position: Int): Fragment {
                  return ItemFragment.create(position)
              }
  
              override fun getItemCount(): Int = 100
          }
  
          val viewpager = findViewById&lt;ViewPager2&gt;(R.id.viewpager).apply {
              offscreenPageLimit = 1
              adapter = pageAdapter
          }
  
          viewpager.currentItem = 0
      }
  
  
      class ItemFragment: Fragment() {
          private var position: Int = 0
  
          companion object {
              private val ARG = ItemFragment::class.java.name+&quot;_arg&quot;
              fun create(position: Int): ItemFragment {
                  return ItemFragment().also {
                      it.arguments = Bundle().apply {
                          putInt(ARG, position)
                      }
                  }
              }
          }
  
          private val TAG: String
              get() = &quot;Fragment_${position}&quot;
  
          override fun onAttach(context: Context) {
              super.onAttach(context)
              position = arguments!!.getInt(ARG, 0)
              Log.d(TAG, &quot;onAttach&quot;)
          }
  
          override fun onDetach() {
              super.onDetach()
              Log.d(TAG, &quot;onDetach&quot;)
          }
  
          override fun onCreate(savedInstanceState: Bundle?) {
              super.onCreate(savedInstanceState)
              Log.d(TAG, &quot;onCreate&quot;)
          }
  
          override fun onStart() {
              super.onStart()
              Log.d(TAG, &quot;onStart&quot;)
          }
  
          override fun onResume() {
              super.onResume()
              Log.d(TAG, &quot;onResume&quot;)
          }
  
          override fun onPause() {
              super.onPause()
              Log.d(TAG, &quot;onPause&quot;)
          }
  
          override fun onStop() {
              super.onStop()
              Log.d(TAG, &quot;onStop&quot;)
          }
  
          override fun onDestroy() {
              super.onDestroy()
              Log.d(TAG, &quot;onDestroy&quot;)
          }
  
          @SuppressLint(&quot;InflateParams&quot;)
          override fun onCreateView(
              inflater: LayoutInflater,
              container: ViewGroup?,
              savedInstanceState: Bundle?
          ): View? {
              Log.d(TAG, &quot;onCreateView&quot;)
              return inflater.inflate(R.layout.item_fragment, null)
          }
  
          override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
              textview.text = position.toString()
              textureview.surfaceTextureListener = object: TextureView.SurfaceTextureListener {
                  override fun onSurfaceTextureSizeChanged(
                      surface: SurfaceTexture?,
                      width: Int,
                      height: Int
                  ) {
                  }
  
                  override fun onSurfaceTextureUpdated(surface: SurfaceTexture?) {
                  }
  
                  override fun onSurfaceTextureDestroyed(surface: SurfaceTexture?): Boolean {
                      Log.d(TAG, &quot;onSurfaceTextureDestroyed&quot;)
                      return true
                  }
  
                  override fun onSurfaceTextureAvailable(
                      surfaceTexture: SurfaceTexture?,
                      width: Int,
                      height: Int
                  ) {
                      Log.d(TAG, &quot;onSurfaceTextureAvailable&quot;)
                      val surface = Surface(surfaceTexture)
                      val canvas = surface.lockCanvas(null)
                      canvas.drawColor(Color.CYAN)
                      surface.unlockCanvasAndPost(canvas)
                      surface.release()
                  }
              }
          }
  
          override fun onDestroyView() {
              super.onDestroyView()
              Log.d(TAG, &quot;onDestroyView&quot;)
          }
  
      }
  
  }
  
  </code></pre>
  <p>And the layout is as following:</p>
  <p>activity_main.xml</p>
  <pre><code>
  &lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
  &lt;FrameLayout xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
      xmlns:tools=&quot;http://schemas.android.com/tools&quot;
      android:layout_width=&quot;match_parent&quot;
      android:layout_height=&quot;match_parent&quot;
      tools:context=&quot;.MainActivity&quot;&gt;
  
      &lt;androidx.viewpager2.widget.ViewPager2
          android:id=&quot;@+id/viewpager&quot;
          android:layout_width=&quot;match_parent&quot;
          android:layout_height=&quot;match_parent&quot; /&gt;
  
  &lt;/FrameLayout&gt;
  </code></pre>
  <p>item_fragment.xml</p>
  <pre><code>&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
  &lt;RelativeLayout xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
      xmlns:tools=&quot;http://schemas.android.com/tools&quot;
      android:layout_width=&quot;match_parent&quot;
      android:layout_height=&quot;match_parent&quot;
      tools:context=&quot;.MainActivity&quot;&gt;
  
      &lt;TextureView
          android:id=&quot;@+id/textureview&quot;
          android:layout_width=&quot;match_parent&quot;
          android:layout_height=&quot;match_parent&quot; /&gt;
      &lt;TextView
          android:id=&quot;@+id/textview&quot;
          android:layout_width=&quot;wrap_content&quot;
          android:layout_height=&quot;wrap_content&quot;
          android:layout_centerInParent=&quot;true&quot; /&gt;
  
  &lt;/RelativeLayout&gt;
  </code></pre>
  <p>The off-screen fragments are created as expected. However, the destroy behavior is not what I am expecting. You can see fragment0 is not destroyed until I scrolled to fragment4. But surface on fragment0 got destroyed when I scrolled to fragment2.</p>
  <pre><code>04-21 17:51:20.527 20921 20921 D Fragment_0: onAttach
  04-21 17:51:20.527 20921 20921 D Fragment_0: onCreate
  04-21 17:51:20.527 20921 20921 D Fragment_0: onCreateView
  04-21 17:51:20.531 20921 20921 D Fragment_0: onStart
  04-21 17:51:20.531 20921 20921 D Fragment_0: onResume
  04-21 17:51:20.533 20921 20921 D Fragment_1: onAttach
  04-21 17:51:20.533 20921 20921 D Fragment_1: onCreate
  04-21 17:51:20.534 20921 20921 D Fragment_1: onCreateView
  04-21 17:51:20.536 20921 20921 D Fragment_1: onStart
  04-21 17:51:20.540 20921 20921 D Fragment_0: onSurfaceTextureAvailable
  04-21 17:51:20.544 20921 20921 D Fragment_1: onSurfaceTextureAvailable
  04-21 17:51:22.082 20921 20921 D Fragment_2: onAttach
  04-21 17:51:22.083 20921 20921 D Fragment_2: onCreate
  04-21 17:51:22.083 20921 20921 D Fragment_2: onCreateView
  04-21 17:51:22.087 20921 20921 D Fragment_2: onStart
  04-21 17:51:22.428 20921 20921 D Fragment_0: onPause
  04-21 17:51:22.428 20921 20921 D Fragment_1: onResume
  04-21 17:51:22.430 20921 20921 D Fragment_2: onSurfaceTextureAvailable
  04-21 17:51:23.342 20921 20921 D Fragment_3: onAttach
  04-21 17:51:23.342 20921 20921 D Fragment_3: onCreate
  04-21 17:51:23.342 20921 20921 D Fragment_3: onCreateView
  04-21 17:51:23.348 20921 20921 D Fragment_3: onStart
  04-21 17:51:23.690 20921 20921 D Fragment_0: onSurfaceTextureDestroyed
  04-21 17:51:23.691 20921 20921 D Fragment_1: onPause
  04-21 17:51:23.691 20921 20921 D Fragment_2: onResume
  04-21 17:51:23.693 20921 20921 D Fragment_3: onSurfaceTextureAvailable
  04-21 17:51:24.452 20921 20921 D Fragment_4: onAttach
  04-21 17:51:24.453 20921 20921 D Fragment_4: onCreate
  04-21 17:51:24.453 20921 20921 D Fragment_4: onCreateView
  04-21 17:51:24.456 20921 20921 D Fragment_4: onStart
  04-21 17:51:24.796 20921 20921 D Fragment_1: onSurfaceTextureDestroyed
  04-21 17:51:24.798 20921 20921 D Fragment_2: onPause
  04-21 17:51:24.798 20921 20921 D Fragment_3: onResume
  04-21 17:51:24.799 20921 20921 D Fragment_4: onSurfaceTextureAvailable
  04-21 17:51:28.500 20921 20921 D Fragment_5: onAttach
  04-21 17:51:28.500 20921 20921 D Fragment_5: onCreate
  04-21 17:51:28.501 20921 20921 D Fragment_5: onCreateView
  04-21 17:51:28.506 20921 20921 D Fragment_5: onStart
  04-21 17:51:28.853 20921 20921 D Fragment_2: onSurfaceTextureDestroyed
  04-21 17:51:28.855 20921 20921 D Fragment_0: onStop
  04-21 17:51:28.855 20921 20921 D Fragment_0: onDestroyView
  04-21 17:51:28.856 20921 20921 D Fragment_0: onDestroy
  04-21 17:51:28.856 20921 20921 D Fragment_0: onDetach
  04-21 17:51:28.857 20921 20921 D Fragment_3: onPause
  04-21 17:51:28.857 20921 20921 D Fragment_4: onResume
  04-21 17:51:28.858 20921 20921 D Fragment_5: onSurfaceTextureAvailable
  </code></pre>
  <p>This is very annoying since the fragment and its surface are not destroyed at the same time. Does anyone have an idea on what is going wrong here?</p>