美文网首页
TabLayout配合ViewPager后不显示标题

TabLayout配合ViewPager后不显示标题

作者: Frank_Kivi | 来源:发表于2018-10-25 22:01 被阅读31次

TabLayout配合ViewPager来做Tab切换是常用的方式。但是有时我们会发现,在调用了android.support.design.widget.TabLayout#setupWithViewPager(android.support.v4.view.ViewPager, boolean, boolean)后,TabLayout的tab反而不显示标题了。

如何解决

需要重写ViewPager的PagerAdapter的android.support.v4.view.PagerAdapter#getPageTitle方法。

原因分析

所有的一切都发生在TabLayout和ViewPager的绑定时。我们来查看setupWithViewPager的源码。有多个重载方法。最终是调用这个。

private void setupWithViewPager(@Nullable ViewPager viewPager, boolean autoRefresh, boolean implicitSetup) {
        if (this.viewPager != null) {
            if (this.pageChangeListener != null) {
                this.viewPager.removeOnPageChangeListener(this.pageChangeListener);
            }

            if (this.adapterChangeListener != null) {
                this.viewPager.removeOnAdapterChangeListener(this.adapterChangeListener);
            }
        }

        if (this.currentVpSelectedListener != null) {
            this.removeOnTabSelectedListener(this.currentVpSelectedListener);
            this.currentVpSelectedListener = null;
        }

        if (viewPager != null) {
            this.viewPager = viewPager;
            if (this.pageChangeListener == null) {
                this.pageChangeListener = new TabLayout.TabLayoutOnPageChangeListener(this);
            }

            this.pageChangeListener.reset();
            viewPager.addOnPageChangeListener(this.pageChangeListener);
            this.currentVpSelectedListener = new TabLayout.ViewPagerOnTabSelectedListener(viewPager);
            this.addOnTabSelectedListener(this.currentVpSelectedListener);
            PagerAdapter adapter = viewPager.getAdapter();
            重点1---------------------------------------------------
            if (adapter != null) {
                this.setPagerAdapter(adapter, autoRefresh);
            }

            if (this.adapterChangeListener == null) {
                this.adapterChangeListener = new TabLayout.AdapterChangeListener();
            }

            this.adapterChangeListener.setAutoRefresh(autoRefresh);
            重点2----------------------------------------------------------
            viewPager.addOnAdapterChangeListener(this.adapterChangeListener);
            this.setScrollPosition(viewPager.getCurrentItem(), 0.0F, true);
        } else {
            this.viewPager = null;
            this.setPagerAdapter((PagerAdapter)null, false);
        }

        this.setupViewPagerImplicitly = implicitSetup;
    }

我们先来看重点1,这时是直接把ViewPager的PagerAdapter取过来,通过android.support.design.widget.TabLayout#setPagerAdapter设置到TabLayout自己身上。

void setPagerAdapter(@Nullable PagerAdapter adapter, boolean addObserver) {
        if (this.pagerAdapter != null && this.pagerAdapterObserver != null) {
            this.pagerAdapter.unregisterDataSetObserver(this.pagerAdapterObserver);
        }

        this.pagerAdapter = adapter;
        if (addObserver && adapter != null) {
            if (this.pagerAdapterObserver == null) {
                this.pagerAdapterObserver = new TabLayout.PagerAdapterObserver();
            }

            adapter.registerDataSetObserver(this.pagerAdapterObserver);
        }

        this.populateFromPagerAdapter();
    }

设置之后又调用android.support.design.widget.TabLayout#populateFromPagerAdapter

 void populateFromPagerAdapter() {
        this.removeAllTabs();
        if (this.pagerAdapter != null) {
            int adapterCount = this.pagerAdapter.getCount();

            int curItem;
            for(curItem = 0; curItem < adapterCount; ++curItem) {
          重点3-----------------------------------------------------
            this.addTab(this.newTab().setText(this.pagerAdapter.getPageTitle(curItem)), false);
            }

            if (this.viewPager != null && adapterCount > 0) {
                curItem = this.viewPager.getCurrentItem();
                if (curItem != this.getSelectedTabPosition() && curItem < this.getTabCount()) {
                    this.selectTab(this.getTabAt(curItem));
                }
            }
        }

    }

在这个方法中清空了所有的tabs,然后又重新add,重点3的代码。是从pageAdapter中的android.support.v4.view.PagerAdapter#getPageTitle取到新的title。

有同学可能会说如果我在android.support.design.widget.TabLayout#setupWithViewPager(android.support.v4.view.ViewPager)调用之后再给ViewPager设置Adapter是不是就可以呢。答案是否定的,请看前面的重点2,

 viewPager.addOnAdapterChangeListener(this.adapterChangeListener);

在setupWithViewPager时,会给ViewPager添加一个OnAdapterChangeListener(如果已经有的话,会先移除,注意看前边的代码),我们来查看一下它的实现。

 if (this.adapterChangeListener == null) {
                this.adapterChangeListener = new TabLayout.AdapterChangeListener();
            }

向后追踪

private class AdapterChangeListener implements OnAdapterChangeListener {
        private boolean autoRefresh;

        AdapterChangeListener() {
        }

        public void onAdapterChanged(@NonNull ViewPager viewPager, @Nullable PagerAdapter oldAdapter, @Nullable PagerAdapter newAdapter) {
            if (TabLayout.this.viewPager == viewPager) {
重点4-----------------------------------------------
                TabLayout.this.setPagerAdapter(newAdapter, this.autoRefresh);
            }

        }

        void setAutoRefresh(boolean autoRefresh) {
            this.autoRefresh = autoRefresh;
        }
    }

重点4所示,最后在ViewPager的Adapter变化时,还是会调用 android.support.design.widget.TabLayout#setPagerAdapter。

相关文章

网友评论

      本文标题:TabLayout配合ViewPager后不显示标题

      本文链接:https://www.haomeiwen.com/subject/ggchtqtx.html