0

I want to create a dialog which contain's ViewPager inside it which have 3 pages and all pages have different layout structure. I want a solution by that i can set the layout content programmatically . I think this can be done by making fragments for each page but i don't know how to do this.

I go through these answers but i am not getting idea how to use them in my case.

Viewpager in Dialog?

ViewPager in Custom Dialog

ViewPager in simple Dialog

Puneet Kumar
  • 381
  • 1
  • 3
  • 11

1 Answers1

0

You can try and build your custom dialog through DialogFragment. Consider the XML layout would contain a ViewPager and the code to go about would be:

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

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

    private fun setupPager() {
        val pagerFragment1 = PagerFragment1.newInstance()
        val pagerFragment2 = PagerFragment2.newInstance()
        val pagerFragment3 = PagerFragment3.newInstance()
        viewPager?.adapter = MyFragmentPagerAdapter(childFragmentManager).apply {
            adapterReference = object : PageAdapterInterface {
                override var fragmentList: List<Fragment> = 
                        mutableListOf(pagerFragment1, pagerFragment2, pagerFragment3)

            }
        }
    }

    companion object {
        const val tag = "PagerDialog"
    }
}

I have used reference to the list because it might cause leaks when not handled correctly. So the PagerAdapterInterface would look like:

interface PageAdapterInterface {
    var fragmentList: List<Fragment>
    fun getItemCount() = fragmentList.size

    @Throws(StackOverflowError::class)
    fun getItemAt(index: Int) : Fragment {
        if (index >= fragmentList.size) throw StackOverflowError()
        return fragmentList[index]
    }
}

Your view pager adapter can make use of this reference in manner that is accessing referentially like:

class MyFragmentPagerAdapter(childFragmentManager: FragmentManager) : FragmentStatePagerAdapter(childFragmentManager){
    lateinit var adapterReference: PageAdapterInterface
    override fun getItem(p0: Int): Fragment = adapterReference.getItemAt(p0)

    override fun getCount(): Int = adapterReference.getItemCount()

}

Finally in your Activity or Fragment on create() or onViewCreated() functions respectively, you can initialize the dialog as shown:

class MyActivity: AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        // use childFragmentManager if the code is
        // used within the Fragment

        val prev = supportFragmentManager.findFragmentByTag(PagerDialog.tag)
        if (prev != null) {
            supportFragmentManager.beginTransaction()
                    .remove(prev)
                    .addToBackStack(null)
                    .commit()
        }
        PagerDialog().show(supportFragmentManager, PagerDialog.tag)
    }
}

Note: DialogFragment is deprecated on > API 28 check out https://developer.android.com/reference/android/app/DialogFragment

HawkPriest
  • 272
  • 2
  • 8
  • thanks for help but i used another method. I popped an Activity as dialog and then use View Pager inside it which contains fragments. – Puneet Kumar Jul 13 '18 at 15:33