public void attach() {
if (attached) {
throw new IllegalStateException("TabLayoutMediator is already attached");
}
adapter = viewPager.getAdapter();
//需要先给ViewPager2设置Adapter
if (adapter == null) {
throw new IllegalStateException(
"TabLayoutMediator attached before ViewPager2 has an " + "adapter");
}
attached = true;
// 给ViewPager 设置监听
onPageChangeCallback = new TabLayoutOnPageChangeCallback(tabLayout);
viewPager.registerOnPageChangeCallback(onPageChangeCallback);
// 给Tablayout 设置监听
onTabSelectedListener = new ViewPagerOnTabSelectedListener(viewPager);
tabLayout.addOnTabSelectedListener(onTabSelectedListener);
// Now we'll populate ourselves from the pager adapter, adding an observer if
// autoRefresh is enabled
if (autoRefresh) {
// Register our observer on the new adapter
pagerAdapterObserver = new PagerAdapterObserver();
adapter.registerAdapterDataObserver(pagerAdapterObserver);
}
//开始初始化tab
populateTabsFromPagerAdapter();
// 根据ViewPager2的当前位置更新TabLayout
tabLayout.setScrollPosition(viewPager.getCurrentItem(), 0f, true);
}
void populateTabsFromPagerAdapter() {
tabLayout.removeAllTabs();
if (adapter != null) {
int adapterCount = adapter.getItemCount();
for (int i = 0; i < adapterCount; i++) {
TabLayout.Tab tab = tabLayout.newTab();
tabConfigurationStrategy.onConfigureTab(tab, i);
tabLayout.addTab(tab, false);
}
// Make sure we reflect the currently set ViewPager item
if (adapterCount > 0) {
int lastItem = tabLayout.getTabCount() - 1;
int currItem = Math.min(viewPager.getCurrentItem(), lastItem);
if (currItem != tabLayout.getSelectedTabPosition()) {
tabLayout.selectTab(tabLayout.getTabAt(currItem));
}
}
}
}
class ProfilePagerAdapter(activity: FragmentActivity, private val fragmentIds: List<Long>)
: FragmentStateAdapter(activity) {
override fun getItemCount(): Int = fragmentIds.size
override fun createFragment(position: Int): Fragment {
//创建新的Fragment
return BaseProfileFragment.create(getItemId(position))
}
override fun containsItem(itemId: Long): Boolean {
return fragmentIds.contains(itemId)
}
override fun getItemId(position: Int): Long {
return fragmentIds[position]
}
}
Fragment 状态管理
对于 fragment 销毁后的状态恢复 ,可以在 oncreateView 方法中的 savedInstanceState 恢复,在 onSaveInstanceState中保存需要保持的数据。
override fun createViewPagerAdapter(): RecyclerView.Adapter<*> {
val items = items // avoids resolving the ViewModel multiple times
return object : FragmentStateAdapter(this) {
override fun createFragment(position: Int): PageFragment {
Log.d(TAG, "createFragment: $position")
val itemId = items.itemId(position)
val itemText = items.getItemById(itemId)
return PageFragment.create(itemText)
}
override fun getItemCount(): Int = items.size
override fun getItemId(position: Int): Long = items.itemId(position)
override fun containsItem(itemId: Long): Boolean = items.contains(itemId)
}
}
PageTransformer
实现ViewPager2.PageTransformer接口
/**
* A PageTransformer is invoked whenever a visible/attached page is scrolled.
* This offers an opportunity for the application to apply a custom transformation
* to the page views using animation properties.
*/
public interface PageTransformer {
/**
* Apply a property transformation to the given page.
*
* @param page Apply the transformation to this page
* @param position Position of page relative to the current front-and-center
* position of the pager. 0 is front and center. 1 is one full
* page position to the right, and -2 is two pages to the left.
* Minimum / maximum observed values depend on how many pages we keep
* attached, which depends on offscreenPageLimit.
*
* @see #setOffscreenPageLimit(int)
*/
void transformPage(@NonNull View page, float position);
}