iis服务器助手广告
返回顶部
首页 > 资讯 > 移动开发 >重学Android之View——TabLayoutMediator解析
  • 157
分享到

重学Android之View——TabLayoutMediator解析

androidjava开发语言 2023-09-10 07:09:04 157人浏览 八月长安
摘要

重学Android之View——TabLayoutMediator解析 1.前言 在使用TabLayout+ViewPager2+Fragment的时候,查询别人的使用例子,看到了 TabLayout

重学Android之View——TabLayoutMediator解析

1.前言

在使用TabLayout+ViewPager2+Fragment的时候,查询别人的使用例子,看到了

TabLayoutMediator这个类,撰写此文,仅当学习思考,本文是在引用material:1.7.0的版本基础上

2.测试效果

Tab + ViewPager2 + Fragment

tab

3.内部成员变量介绍

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关于数据的监听类

4.TabLayoutOnPageChangeCallback

这个是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;    }  }

5.ViewPagerOnTabSelectedListener

这个是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    }  }

6.ViewPagerOnTabSelectedListener

通过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));        }      }    }  }

7.结合ViewPager2跟TabLayout

在这里去注册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

8.外界使用TabLayoutMediator的简单调用事例

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文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作