Android ViewPager2碎片销毁行为不符合OffscreenPageLimit的规定。

问题描述 投票:1回答:1

我使用ViewPager2与FragmentStatePagerAdapter,并设置OffscreenPageLimit=1。每个片段都包含一个表面(通过TextureView获得),要在上面绘制。

代码相当简单。

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<ViewPager2>(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+"_arg"
            fun create(position: Int): ItemFragment {
                return ItemFragment().also {
                    it.arguments = Bundle().apply {
                        putInt(ARG, position)
                    }
                }
            }
        }

        private val TAG: String
            get() = "Fragment_${position}"

        override fun onAttach(context: Context) {
            super.onAttach(context)
            position = arguments!!.getInt(ARG, 0)
            Log.d(TAG, "onAttach")
        }

        override fun onDetach() {
            super.onDetach()
            Log.d(TAG, "onDetach")
        }

        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            Log.d(TAG, "onCreate")
        }

        override fun onStart() {
            super.onStart()
            Log.d(TAG, "onStart")
        }

        override fun onResume() {
            super.onResume()
            Log.d(TAG, "onResume")
        }

        override fun onPause() {
            super.onPause()
            Log.d(TAG, "onPause")
        }

        override fun onStop() {
            super.onStop()
            Log.d(TAG, "onStop")
        }

        override fun onDestroy() {
            super.onDestroy()
            Log.d(TAG, "onDestroy")
        }

        @SuppressLint("InflateParams")
        override fun onCreateView(
            inflater: LayoutInflater,
            container: ViewGroup?,
            savedInstanceState: Bundle?
        ): View? {
            Log.d(TAG, "onCreateView")
            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, "onSurfaceTextureDestroyed")
                    return true
                }

                override fun onSurfaceTextureAvailable(
                    surfaceTexture: SurfaceTexture?,
                    width: Int,
                    height: Int
                ) {
                    Log.d(TAG, "onSurfaceTextureAvailable")
                    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, "onDestroyView")
        }

    }

}

布局如下:

activity_main.xml


<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <androidx.viewpager2.widget.ViewPager2
        android:id="@+id/viewpager"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</FrameLayout>

item_fragment.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextureView
        android:id="@+id/textureview"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
    <TextView
        android:id="@+id/textview"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true" />

</RelativeLayout>

屏幕外的碎片是按照预期创建的。然而,销毁行为并不是我所期望的。你可以看到fragment0没有被销毁,直到我滚动到fragment4。但是当我滚动到fragment2时,fragment0上的surface被销毁了。

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

这是非常恼人的,因为碎片和它的表面不是同时被破坏的。有谁知道这是怎么回事吗?

android android-fragments fragmentstatepageradapter android-viewpager2
1个回答
© www.soinside.com 2019 - 2024. All rights reserved.