Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
212 views
in Technique[技术] by (71.8m points)

android - Why is my Viewpager not showing any fragments after opening the second time and why can childfragmentmanager not be used?

I have a Fragment (InnerFragment) placed inside a Viewpager (MainViewPager).

This Fragment (InnerFragment) does also contain a ViewPager (NestedViewPager) with multiple Fragments. When I swipe or open the InnerFragment everything works fine and the NestedViewPager shows all Fragments the way it should.

When I leave the InnerFragment after swiping the MainViewPager and go back to the InnerFragment it is blank and nothing shows up.

One solution as described in the internet is using the childfragmentmanager. Unfortunately this doesn't work because if I do so following exception is thrown.

java.lang.IllegalStateException: Fragment ProductImageFragment{c458f99 (1213d869-3715-4541-8nab-f87cyc350630) id=0x8f093165 android:switcher:2111xxxxxx:0} declared target fragment ProductImagesFragment{4b4f25e (99a6aaf6-5500-4821-902f-7bf30f87554c) id=0x7f090126 android:switcher:2131296550:2} that does not belong to this FragmentManager!
        at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:805)

Maybe it is also important to note, that the MainFragment is implementing an Interface of the Innerfragment.

MainFragment

class ProductImagesFragment : Fragment(),
    ProductImageFragment.IProductImageHandler,
    ProductImageUploadDialog.ProductImageUploadDialogEventListener {

    private lateinit var viewPager: ViewPager

    interface IProductImageUploadHandler{
        fun onImageUploadToServerFinished(bitmap: Bitmap, imageData: ProductImage)
    }

    override fun onCreate(savedInstanceState: Bundle?)
    {
        super.onCreate(savedInstanceState)
    }
   

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View?
    {
        return layoutInflater.inflate(R.layout.fragment_product_images,container,false)
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        viewPager = view.findViewById(R.id.viewPagerImages)
        setViewPagerAdapter()
    }

    private fun setViewPagerAdapter(){
        val manager = fragmentManager
        if(manager!=null){
            viewPager.adapter = product?.let {product ->
                ImageAdapter(this,
                    product,productImageList,manager)
            }
        }
    }

class ImageAdapter(private val productImagesFragment: ProductImagesFragment, private val product: Product, private val imagesList:ArrayList<ProductImage>, fragmentManager: FragmentManager) : FragmentPagerAdapter(fragmentManager) {

        override fun getCount(): Int {
            return imagesList.size
        }

        override fun getItem(position: Int): Fragment {
            val fragment = ProductImageFragment()
            val bundle = Bundle()
            val image = imagesList[position]
            bundle.putInt("productId",product.id)
            bundle.putParcelable("productImage",image)
            bundle.putInt("maxImages",imagesList.size)
            fragment.setTargetFragment(productImagesFragment,1)
            fragment.arguments = bundle
            return fragment
        }
    }


}

InnerFragment

class ProductImageFragment : Fragment() {

    private lateinit var productImageHandler: IProductImageHandler

    interface IProductImageHandler{
        fun onImageDeleted(id: Int)
        fun onOrderChanged(url: String, newValue: Int, oldValue: Int)
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
    }

    override fun onAttach(context: Context) {
        super.onAttach(context)
        try {
            productImageHandler = targetFragment as IProductImageHandler
        }catch (exception: Exception){
        }
    }

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        return inflater.inflate(R.layout.fragment_product_image, container, false)
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
       
    }

    private fun setValues(view: View){
        
    }
}

question from:https://stackoverflow.com/questions/65928024/why-is-my-viewpager-not-showing-any-fragments-after-opening-the-second-time-and

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You must use the childFragmentManager in order for the state to be restored properly.

You shouldn't be using the target fragment API at all. In fact, if you're using the childFragmentManager, your child fragments already have a reference to the parent via requireParentFragment() - just use that instead of targetFragment.

override fun onAttach(context: Context) {
    super.onAttach(context)
    try {
         productImageHandler = requireParentFragment() as IProductImageHandler
    }catch (exception: Exception){
    }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...