Android ViewPager fragment swap

A ViewPager hosts a list of fragments, each page contains a fragment. The following demonstrates swapping a fragment on a page in ViewPager. Take page 0 for example, there is a button on the fragment, when that button is clicked, the fragment on page 0 will be replaced with another fragment and if the back button is pressed, it will go back to the previous fragment that was on page 0.

MainActivity.kl, this activity is the main screen that hosts the viewpager, and a adapter for managing the fragments within the viewpager.

import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.support.v4.app.Fragment
import android.support.v4.app.FragmentManager
import android.support.v4.app.FragmentPagerAdapter
import android.support.v4.view.ViewPager
import kotlinx.android.synthetic.main.activity_main.*

// https://github.com/danilao/fragments-viewpager-example/tree/master/src/com/pineappslab/frcontainer
class MainActivity : AppCompatActivity() {

    val NUM_ITEMS = 5
    private lateinit var mPagerAdapter: SlidePagerAdapter

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        mPagerAdapter = SlidePagerAdapter(supportFragmentManager)
        pager.adapter = mPagerAdapter

        pager.addOnPageChangeListener(object: ViewPager.OnPageChangeListener {
            override fun onPageScrollStateChanged(state: Int) {
            }

            override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {

            }

            override fun onPageSelected(position: Int) {
                if (position > 1) {
                    // java.lang.IllegalArgumentException: No view found for id 0x7f070055 (com.example.viewpagerfragmentswap:id/root_frame) for fragment SecondFragment
                    for (i in 0 until supportFragmentManager.backStackEntryCount) {
                        supportFragmentManager.popBackStack()
                    }
                }
            }
        })

    }

    inner class SlidePagerAdapter(val fm: FragmentManager) : FragmentPagerAdapter(fm) {

        override fun getItem(position: Int): Fragment {

            return if (position == 0) {
                RootFragment() // This is where we create a RootFragment acting as a container for other fragments
            } else {
                StaticFragment()
            }
        }

        override fun getCount(): Int {
            return NUM_ITEMS
        }
    }
}

StaticFragment.kl, a default normal fragment on the ViewPager, no fragment swapping operations.

import android.os.Bundle
import android.support.v4.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup

class StaticFragment : Fragment() {

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

RootFragment.kl, this is the special fragment on the ViewPager which can swap or change fragments. It will be the parent of other fragments that can be swapped in and out.

import android.os.Bundle
import android.support.v4.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup

class RootFragment : Fragment() {

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

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

        val transaction = fragmentManager.beginTransaction()

		 // When this container fragment is created, we fill it with our first "real" fragment
        transaction.replace(R.id.root_frame, FirstFragment())
        transaction.commit()
    }
}

FirstFragment.kl, the first fragment lives inside the RootFragment, clicking the button on this fragment will replace this fragment with SecondFragment.kl

import android.os.Bundle
import android.support.v4.app.Fragment
import android.support.v4.app.FragmentTransaction
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import kotlinx.android.synthetic.main.first_fragment.*

class FirstFragment : Fragment() {

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

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

        btn.setOnClickListener {
            val trans = fragmentManager.beginTransaction()

            // We use the "root frame" defined in "root_fragment.xml" as the reference to replace fragment
            trans.replace(R.id.root_frame, SecondFragment())

            // The following lines allow us to add the fragment to the stack and return to it later, by pressing back
            trans.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
            trans.addToBackStack(null)
            trans.commit()
        }
    }
}

SecondFragment.kl

import android.os.Bundle
import android.support.v4.app.Fragment
import android.support.v4.app.FragmentTransaction
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import kotlinx.android.synthetic.main.second_fragment.*

class SecondFragment : Fragment() {

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

    override fun onViewCreated(view: View?, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        btn.setOnClickListener {
            val trans = fragmentManager.beginTransaction()
            trans.replace(R.id.root_frame, StaticFragment())
            trans.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
            trans.addToBackStack(null)
            trans.commit()
        }
    }
}

Complete example in Github

Search within Codexpedia

Custom Search

Search the entire web

Custom Search