重学Android之View——TabLayoutMediator解析 1.前言 在使用TabLayout+ViewPager2+Fragment的时候,查询别人的使用例子,看到了 TabLayout
在使用TabLayout+ViewPager2+Fragment的时候,查询别人的使用例子,看到了
TabLayoutMediator这个类,撰写此文,仅当学习思考,本文是在引用material:1.7.0的版本基础上
Tab + ViewPager2 + Fragment
public final class TabLayoutMediator { @NonNull private final TabLayout tabLayout; @NonNull private final ViewPager2 viewPager; private final boolean autoRefresh; private final boolean smoothScroll; private final TabConfigurationStrategy tabConfigurationStrategy; @Nullable private RecyclerView.Adapter<?> adapter; private boolean attached; @Nullable private TabLayoutOnPageChangeCallback onPageChangeCallback; @Nullable private TabLayout.OnTabSelectedListener onTabSelectedListener; @Nullable private RecyclerView.AdapterDataObserver pagerAdapterObserver; ......
TabLayoutMediator类引用了tabLayout跟ViewPager2对象,另外内部定义定义了tabLayout跟Viewpager2的
监听回调类,还有adapter关于数据的监听类
这个是viewPager2的监听类,主要目的是,在viewPager2发生页面变化的时候,去同步更新TabLaout的状态
,通过使用如下TabLaout的api去更新tabLayout的状态
tabLayout.selectTab() tabLayout.setScrollPosition()
并且通过如下方法,注册到viewPager的监听器中
viewPager.reGISterOnPageChangeCallback();
具体的ViewPager2.OnPageChangeCallback的监听类,在这里不仔细介绍
private static class TabLayoutOnPageChangeCallback extends ViewPager2.OnPageChangeCallback { @NonNull private final WeakReference<TabLayout> tabLayoutRef; private int previousScrollState; private int scrollState; TabLayoutOnPageChangeCallback(TabLayout tabLayout) { tabLayoutRef = new WeakReference<>(tabLayout); reset(); } @Override public void onPageScrollStateChanged(final int state) { previousScrollState = scrollState; scrollState = state; } @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { TabLayout tabLayout = tabLayoutRef.get(); if (tabLayout != null) { // Only update the text selection if we're not settling, or we are settling after // being dragged boolean updateText = scrollState != SCROLL_STATE_SETTLING || previousScrollState == SCROLL_STATE_DRAGGING; // Update the indicator if we're not settling after being idle. This is caused // from a setCurrentItem() call and will be handled by an animation from // onPageSelected() instead. boolean updateIndicator = !(scrollState == SCROLL_STATE_SETTLING && previousScrollState == SCROLL_STATE_IDLE); tabLayout.setScrollPosition(position, positionOffset, updateText, updateIndicator); } } @Override public void onPageSelected(final int position) { TabLayout tabLayout = tabLayoutRef.get(); if (tabLayout != null && tabLayout.getSelectedTabposition() != position && position < tabLayout.getTabCount()) { // Select the tab, only updating the indicator if we're not being dragged/settled // (since onPageScrolled will handle that). boolean updateIndicator = scrollState == SCROLL_STATE_IDLE || (scrollState == SCROLL_STATE_SETTLING && previousScrollState == SCROLL_STATE_IDLE); tabLayout.selectTab(tabLayout.getTabAt(position), updateIndicator); } } void reset() { previousScrollState = scrollState = SCROLL_STATE_IDLE; } }
这个是TabLayout的监听类,主要目的是,在TabLayout发生页面变化的时候,去同步更新ViewPager2的状态
主要通过ViewPager2的Api,来更新状态viewPager2的状态
viewPager.setCurrentItem
通过tabLayout的addOnTabSelectedListener 方法来添加监听
tabLayout.addOnTabSelectedListener()
private static class ViewPagerOnTabSelectedListener implements TabLayout.OnTabSelectedListener { private final ViewPager2 viewPager; private final boolean smoothScroll; ViewPagerOnTabSelectedListener(ViewPager2 viewPager, boolean smoothScroll) { this.viewPager = viewPager; this.smoothScroll = smoothScroll; } @Override public void onTabSelected(@NonNull TabLayout.Tab tab) { viewPager.setCurrentItem(tab.getPosition(), smoothScroll); } @Override public void onTabUnselected(TabLayout.Tab tab) { // No-op } @Override public void onTabReselected(TabLayout.Tab tab) { // No-op } }
通过viewPager2的适配器监听类来更新的tabLayout状态
private class PagerAdapterObserver extends RecyclerView.AdapterDataObserver { PagerAdapterObserver() {} @Override public void onChanged() { populateTabsFromPagerAdapter(); } @Override public void onItemRangeChanged(int positionStart, int itemCount) { populateTabsFromPagerAdapter(); } @Override public void onItemRangeChanged(int positionStart, int itemCount, @Nullable Object payload) { populateTabsFromPagerAdapter(); } @Override public void onItemRangeInserted(int positionStart, int itemCount) { populateTabsFromPagerAdapter(); } @Override public void onItemRangeRemoved(int positionStart, int itemCount) { populateTabsFromPagerAdapter(); } @Override public void onItemRangeMoved(int fromPosition, int toPosition, int itemCount) { populateTabsFromPagerAdapter(); } }中
从上面的ViewPager2的适配器监听 ,收到数据的变化,就去更新tabLayout 状态,调用populateTabsFromPagerAdapter 函数
主要是根据数据的条目,更新tab的数量,然后,添加到tabLayout 中,注意,在这里通过接口回调的方式,回调了onConfigureTab方法,
调用者,就能够得到里面的tab的相关信息
@SuppressWarnings("WeakerAccess") 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)); } } } }
在这里去注册viewPager2跟Tablayout的各种监听,以及去初始化填充
public void attach() { if (attached) { throw new IllegalStateException("TabLayoutMediator is already attached"); } adapter = viewPager.getAdapter(); if (adapter == null) { throw new IllegalStateException( "TabLayoutMediator attached before ViewPager2 has an " + "adapter"); } attached = true; // Add our custom OnPageChangeCallback to the ViewPager onPageChangeCallback = new TabLayoutOnPageChangeCallback(tabLayout); viewPager.registerOnPageChangeCallback(onPageChangeCallback); // Now we'll add a tab selected listener to set ViewPager's current item onTabSelectedListener = new ViewPagerOnTabSelectedListener(viewPager, smoothScroll); 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); } populateTabsFromPagerAdapter(); // Now update the scroll position to match the ViewPager's current item tabLayout.setScrollPosition(viewPager.getCurrentItem(), 0f, tru
adapter = new ViewPagerFragmentAdapter(this, labels); viewPager2.setAdapter(adapter); TabLayoutMediator mediator = new TabLayoutMediator(tabLayout, viewPager2, new TabLayoutMediator.TabConfigurationStrategy() { @Override public void onConfigureTab(@NonNull TabLayout.Tab tab, int position) { tab.setText(labels[position]); } }); viewPager2.setCurrentItem(2, false); mediator.attach();
来源地址:https://blog.csdn.net/g241893312/article/details/128723023
--结束END--
本文标题: 重学Android之View——TabLayoutMediator解析
本文链接: https://www.lsjlt.com/news/402068.html(转载时请注明来源链接)
有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341
下载Word文档到电脑,方便收藏和打印~
2024-01-21
2023-10-28
2023-10-28
2023-10-27
2023-10-27
2023-10-27
2023-10-27
回答
回答
回答
回答
回答
回答
回答
回答
回答
回答
0