从 Viewpager2 片段访问父片段函数

Posted

技术标签:

【中文标题】从 Viewpager2 片段访问父片段函数【英文标题】:Accessing Parent's Fragment function from Viewpager2 fragment 【发布时间】:2020-12-31 02:41:15 【问题描述】:

我正在使用导航组件,并且在我的主页片段中有一个 ViewPager2。我们知道 viewPager2 也包含 Fragment。如何通过viewpager2的片段调用父函数?我尝试了一些方法,比如在构造函数中传递函数,但我实现了使用单例模式创建的片段。我只知道如何在构造函数中传递函数,比如标准类(不是单例类)

我的适配器

class DetailSliderAdapter(fragmentActivity: FragmentActivity) : FragmentStateAdapter(fragmentActivity) 

    private val images = mutableListOf<String>()

    fun addImages(lsImage: List<String>)
        images.addAll(lsImage)
        notifyDataSetChanged()
    

    override fun getItemCount(): Int = images.size
    override fun createFragment(position: Int): Fragment 
        return SliderImageFragment.newInstance(images[position])
    

    class SliderImageFragment: Fragment()
        companion object
            const val EXTRA_SLIDER_IMAGE = "extra_slider_image"
            fun newInstance(imageStr: String) = SliderImageFragment().apply 
                this.arguments = Bundle().apply 
                    this.putString(EXTRA_SLIDER_IMAGE, imageStr)
                
            

        

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

        override fun onActivityCreated(savedInstanceState: Bundle?) 
            super.onActivityCreated(savedInstanceState)

            val image = arguments?.getString(EXTRA_SLIDER_IMAGE) as? String

            image?.let 
                Picasso.get()
                    .load(image)
                    .into(image_slide)

                image_slide.setOnClickListener 
                    
                    // here i want to call parent's Fragment  function
              
            
        
    

我的片段之家

class DetailFragment : Fragment() 
    private var root: View ?= null
    private var viewpagerSlider : ViewPager2 ?= null

    private val viewModel : DetailViewModel by lazy 
        ViewModelProviders.of(this, factory).get(DetailViewModel::class.java)
    

    private val adapterSlider : DetailSliderAdapter by lazy 
        DetailSliderAdapter(requireActivity())
            //listener
        
    

    fun clearAllAdapter()
        // NEED TO CALL THIS
    

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? 
        val safeArgs : DetailFragmentArgs by navArgs<DetailFragmentArgs>()
        idProduct = safeArgs.idProduct
        Timber.d("ID PRODUCT $idProduct")

        if(root == null)
            root = inflater.inflate(R.layout.fragment_detail, container, false)
            idProduct?.let 
                viewModel.getDetail(idProduct!!)
            
        
        return root
    


    override fun onViewCreated(view: View, savedInstanceState: Bundle?) 
        super.onViewCreated(view, savedInstanceState)

        Timber.d("CALL onViewCreated")

        viewModel.getDataDetail().observe(viewLifecycleOwner, Observer 
            when(it.status)
                
                Response.ResponseStatus.LOADED -> 
                    progress_circular.visibility = View.GONE
                    val data = it.data
                    data?.let  d->
                        val detailProduct = d.detailProduct
                        detailProduct?.let  pd->
                            updateUI(pd, data)
                        

                    
                
               
            

        )
    

    private fun updateUI(pd: ProductDetail, data: Data) 
        pd.image?.let 
            updateSliderPhoto(pd.image)
        
    

    private fun updateSliderPhoto(
        image: List<String>
    ) 
        viewpagerSlider = root?.findViewById(R.id.slider_photo)
        adapterSlider.addImages(image)

        viewpagerSlider?.apply 
            this.adapter = adapterSlider
            this.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback()
                override fun onPageSelected(position: Int) 
                    super.onPageSelected(position)
                    page_indicator.text = "$(position+1)/$image.size"
                
            )
        
    


【问题讨论】:

【参考方案1】:

你不应该永远Fragment 中将FragmentActivity 传递给你的FragmentStateAdapter - 这就是为什么有一个FragmentStateAdapter 构造函数接受Fragment。只有Fragment 构造函数才能将ViewPager2 片段正确嵌套在您的父片段中。

使用正确的构造函数后,您的SliderImageFragment 可以调用requireParentFragment() 并将其转换为DetailFragment 并调用您的方法。

【讨论】:

终于成功了,我用 currentFragment 改变了 fragmentActivity。谢谢楼主

以上是关于从 Viewpager2 片段访问父片段函数的主要内容,如果未能解决你的问题,请参考以下文章

如何在另一个片段中访问和使用一个片段的按钮?

如何更新 Tablayout 中的片段? (Viewpager2, FragmentStateAdapter)

从片段访问父活动的数据

ViewPager2 无法动态添加删除片段

带有 Viewpager2 的关键 FragmentStateAdapter 的片段不再存在

带有片段和 Jetpack 导航的 Viewpager2:恢复片段而不是重新创建它们