Last active
February 2, 2022 16:43
-
-
Save Kolyall/f030f540efe25845e7b9abf9735dbe0b to your computer and use it in GitHub Desktop.
FragmentStatePagerAdapter
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class FavMainAdapter constructor( | |
val context: Context?, | |
fragmentManager: FragmentManager | |
) : BaseFragmentPagerAdapter(fragmentManager) { | |
override fun createItem(position: Int): BaseFragment { | |
return when (position) { | |
0 -> MyCollectionsFragment() | |
1 -> MyPlaylistsFragment() | |
else -> throw IndexOutOfBoundsException("IndexOutOfBounds $position") | |
} | |
} | |
override fun getCount(): Int { | |
return 2 | |
} | |
override fun getPageTitle(position: Int): CharSequence? { | |
val item = FavMainPagerItem.values()[position] | |
return context?.getString(item.titleId) | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class FavMainFragment | |
pagerAdapter override fun onViewCreated(view: View, savedInstanceState: Bundle?) { | |
super.onViewCreated(view, savedInstanceState) | |
setupViewPager() | |
tabLayout.setViewPager(viewPager) | |
} | |
private fun setupViewPager() { | |
pagerAdapter = FavMainAdapter(activity, childFragmentManager) | |
viewPager.isStopScrollWhenTouch = false | |
viewPager.adapter = pagerAdapter | |
viewPager.currentItem = FavMainPagerItem.COLLECTIONS.ordinal | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
abstract class BaseFragmentPagerAdapter( | |
open val fragmentManager: FragmentManager | |
) : FragmentStatePagerAdapter(fragmentManager, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) { | |
/** | |
* State key for the fragment super state. | |
*/ | |
private val ADS_FRAGMENT_STATE_SUPER_STATE = "superState" | |
/** | |
* State key for the fragment pages. | |
*/ | |
private val ADS_FRAGMENT_STATE_PAGES_COUNT = "pages_count" | |
/** | |
* A list of fragments displayed by this adapter. | |
*/ | |
private val pages = SparseArray<BaseFragment>() | |
fun addFragment(fragment: BaseFragment, position: Int = -1) { | |
val index = if (position == -1) pages.size() else position | |
pages.put(index, fragment) | |
} | |
override fun getItem(position: Int): Fragment { | |
val fragment = createItem(position) | |
addFragment(fragment, position) | |
return fragment | |
} | |
override fun getItemPosition(item: Any): Int { | |
// Causes adapter to reload all Fragments when | |
// notifyDataSetChanged is called | |
return PagerAdapter.POSITION_NONE | |
} | |
abstract fun createItem(position: Int): BaseFragment | |
override fun destroyItem(container: ViewGroup, position: Int, item: Any) { | |
if (pages.indexOfKey(position) >= 0) { | |
pages.remove(position) | |
} | |
super.destroyItem(container, position, item) | |
} | |
override fun saveState(): Parcelable? { | |
val parcelable = super.saveState() | |
val bundle = Bundle() | |
bundle.putParcelable(ADS_FRAGMENT_STATE_SUPER_STATE, parcelable) | |
bundle.putInt(ADS_FRAGMENT_STATE_PAGES_COUNT, pages.size()) | |
if (count > 0) { | |
for (i in 0 until count) { | |
val position = pages.keyAt(i) | |
bundle.putInt(i.cacheIndex(), position) | |
val fragment = pages.get(position) | |
fragmentManager.putFragment(bundle, position.cacheKey(), fragment) | |
} | |
} | |
return bundle | |
} | |
override fun restoreState(state: Parcelable?, loader: ClassLoader?) { | |
try { | |
val bundle = state as? Bundle ?: return | |
val pageCount = bundle.getInt(ADS_FRAGMENT_STATE_PAGES_COUNT) | |
if (pageCount > 0) { | |
for (i in 0 until pageCount) { | |
val position = bundle.getInt(i.cacheIndex()) | |
val fragment = fragmentManager.getFragment(bundle, position.cacheKey()) as BaseFragment | |
addFragment(fragment, position) | |
} | |
} | |
val parcelable = bundle.getParcelable<Parcelable?>(ADS_FRAGMENT_STATE_SUPER_STATE) | |
super.restoreState(parcelable, loader) | |
} catch (e: Exception) { | |
Log.e("TAG", "Error Restore State of Fragment : " + e.message, e) | |
} | |
} | |
fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { | |
for (i in 0 until count) { | |
val fragment = pages.get(i) ?: continue | |
fragment.onActivityResult(requestCode, resultCode, data) | |
} | |
} | |
fun onHandleBackPress(): Boolean { | |
var handled = false | |
for (i in 0 until count) { | |
val fragment = pages.get(i) ?: continue | |
if (fragment.onHandleBackPress()) handled = true | |
} | |
return handled | |
} | |
fun setRestoredFromBackstack(restoredFromBackstack: Boolean) { | |
for (i in 0 until count) { | |
val fragment = pages.get(i) ?: continue | |
fragment.isRestoredFromBackstack = restoredFromBackstack | |
} | |
} | |
fun setRetainInstance(retain: Boolean) { | |
for (i in 0 until count) { | |
val fragment = pages.get(i) ?: continue | |
fragment.retainInstance = retain | |
} | |
} | |
} | |
/** | |
* Create an index string for caching fragment pages. | |
* | |
* @param index The index of the item in the adapter. | |
* | |
* @return The key string for caching fragment pages. | |
*/ | |
private fun Int.cacheIndex(): String { | |
return "pageIndex:$this" | |
} | |
/** | |
* Create a key string for caching fragment pages. | |
* | |
* @param position The position of the item in the adapter. | |
* | |
* @return The key string for caching fragment pages. | |
*/ | |
private fun Int.cacheKey(): String { | |
return "page:$this" | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment