Skip to content

Instantly share code, notes, and snippets.

@mnishiguchi
Last active June 30, 2017 21:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mnishiguchi/a425e5d6d6d7b5a4fb2e769a0a416530 to your computer and use it in GitHub Desktop.
Save mnishiguchi/a425e5d6d6d7b5a4fb2e769a0a416530 to your computer and use it in GitHub Desktop.
Android - ViewPager

ViewPager

  • https://developer.android.com/reference/android/support/v4/view/ViewPager.html
  • only available in the support library.
  • Requires a PagerAdapter
  • Use FragmentStatePagerAdapter, a subclass of PagerAdapter to take care of the details
  • By default, ViewPager loads the item currently on screen plus one neighboring page in each direction so that the response to a swipe is immediate.
  • By default, hte ViewPager shows the first item in its PagerAdapter

How to implement it?

  1. Create a layout file for that activity, using android.support.v4.view.ViewPager
  2. Create an activity that is an subclass of FragmentActivity
  3. Inflate the view
  4. Prepare the data set
  5. Set up the pager adapter
    • Get a fragmentManager
    • Implement FragmentStatePagerAdapter's getItem(...) and getCount()
  6. Set the initial pager item
  7. Don't forget to add the newly-created activity to the manifest

Layout

<android.support.v4.view.ViewPager
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/crimePager"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

Activity

/**
 * Inherit FragmentActivity because we use support fragments.
 * A ViewPager is only available in the support library and requires a PagerAdapter, such as
 * FragmentStatePagerAdapter and FragmentPagerAdapter.
 * https://developer.android.com/reference/android/support/v4/view/ViewPager.html
 */
class CrimePagerActivity : FragmentActivity() {
    private val TAG = javaClass.simpleName

    companion object {
        private val EXTRA_CRIME_ID = "${CrimePagerActivity::class.java.canonicalName}.EXTRA_CRIME_ID"

        // Define an extra intent for starting this activity.
        fun newIntent(packageContext: Context, crimeId: UUID): Intent {
            return Intent(packageContext, CrimePagerActivity::class.java).apply {
                putExtra(EXTRA_CRIME_ID, crimeId)
            }
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        Log.d(TAG, "onCreate")
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_crime_pager)

        // Get a crime id from the intent so that we can determine the initial item.
        val crimeId = intent.getSerializableExtra(EXTRA_CRIME_ID) as UUID

        val crimes = CrimeLab.get(this).crimes

        crimePager.adapter = object : FragmentStatePagerAdapter(supportFragmentManager) {
            override fun getItem(position: Int): Fragment = CrimeFragment.newInstance(crimes[position].id)
            override fun getCount(): Int = crimes.size
        }

        // Set initial pager item based on the id provided by the previous activity.
        crimePager.currentItem = crimes.indexOfFirst { it.id == crimeId }
    }
}

FragmentStatePagerAdapter vs FragmentPagerAdapter

  • Only different when a fragment is no longer needed

FragmentStatePagerAdapter

  • Calls remove(fragment) on the transaction
  • Destroys the unneeded fragment
  • The state will be saved using the fragment's Bundle from onSavedInstanceState(Bundle)
  • When the user navigated back, the new fragment will be restored using that instance state.
  • More frugal with memory
  • E.g., a list of items

FragmentPagerAdapter

  • Calls detach(fragment) on the transaction
  • Unneeded fragment is destroyed
  • Destroys the unneeded fragment's view, but leaves the fragment instance alive in the FragmentManager.
  • The fragments created by FragmentPagerAdapter are never destroyed.
  • Suitable with a small interface a fixed number of fragments.
  • E.g., a tabbed interface

Customizing the PagerAdaper interface

  • When we want to host something other than Fragments, such as normal View objects in a ViewPager, we need to implement the raw PagerAdapter interface.
  • PagerAdapter is more complicated then Adapter because it does more of the work of managing views than Adapter does.
  • Instead of onBindViewHolder(...), PagerAdapter has:
    • instantiateItem(ViewGroup container, int pos)
    • destroyItem(ViewGroup container, int pos, Object o)
    • isViewFromObject(View v, Object o)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment