TabLayout踩坑

TabLayout踩坑傳奇

今天中午休息的時候鸟款,同事研究起了MD顿乒,對!就是傳說中的Material design刷允。他想要寫一個MD主題的app,可是遇到個關于TabLayout的問題恩掷。本來想做出的效果是這個樣子的倡鲸。

想象中的效果
想象中的效果

好了開工,寫完一運行黄娘,額峭状,完全不對啊逼争!我的title呢宁炫??氮凝!
img
img
title不見了G鄣蕖月杉!
title不見了!!

我好奇的過去瞅瞅病袄,看了看凌外。沒有問題啊佑女。

 private void initViews() {
        tabLayout.addTab(tabLayout.newTab().setText("ftm1"));
        tabLayout.addTab(tabLayout.newTab().setText("ftm2"));
        viewPager.setAdapter(new FragmentStatePagerAdapter(getSupportFragmentManager()) {
            @Override
            public Fragment getItem(int position) {
                return fragments.get(position);
            }

            @Override
            public int getCount() {
                return fragments == null ? 0 : fragments.size();
            }
        });
        tabLayout.setupWithViewPager(viewPager);
    }

設置了tab也加上了setupWithViewPager方法啊奥秆。查閱了一番資料,是調用setupWithViewPager方法將所有tab清除了傅是。不說廢話了上代碼匪燕,看下是怎么移除tab的:

public void setupWithViewPager(@Nullable final ViewPager viewPager, boolean autoRefresh) {
        setupWithViewPager(viewPager, autoRefresh, false);
    }

    private void setupWithViewPager(@Nullable final ViewPager viewPager, boolean autoRefresh,
            boolean implicitSetup) {
        if (mViewPager != null) {
            // If we've already been setup with a ViewPager, remove us from it
            if (mPageChangeListener != null) {
                mViewPager.removeOnPageChangeListener(mPageChangeListener);
            }
            if (mAdapterChangeListener != null) {
                mViewPager.removeOnAdapterChangeListener(mAdapterChangeListener);
            }
        }

        if (mCurrentVpSelectedListener != null) {
            // If we already have a tab selected listener for the ViewPager, remove it
            removeOnTabSelectedListener(mCurrentVpSelectedListener);
            mCurrentVpSelectedListener = null;
        }

        if (viewPager != null) {
            mViewPager = viewPager;

            // Add our custom OnPageChangeListener to the ViewPager
            if (mPageChangeListener == null) {
                mPageChangeListener = new TabLayoutOnPageChangeListener(this);
            }
            mPageChangeListener.reset();
            viewPager.addOnPageChangeListener(mPageChangeListener);

            // Now we'll add a tab selected listener to set ViewPager's current item
            mCurrentVpSelectedListener = new ViewPagerOnTabSelectedListener(viewPager);
            addOnTabSelectedListener(mCurrentVpSelectedListener);

            final PagerAdapter adapter = viewPager.getAdapter();
            if (adapter != null) {
                // Now we'll populate ourselves from the pager adapter, adding an observer if
                // autoRefresh is enabled
                setPagerAdapter(adapter, autoRefresh);
            }

            // Add a listener so that we're notified of any adapter changes
            if (mAdapterChangeListener == null) {
                mAdapterChangeListener = new AdapterChangeListener();
            }
            mAdapterChangeListener.setAutoRefresh(autoRefresh);
            viewPager.addOnAdapterChangeListener(mAdapterChangeListener);

            // Now update the scroll position to match the ViewPager's current item
            setScrollPosition(viewPager.getCurrentItem(), 0f, true);
        } else {
            // We've been given a null ViewPager so we need to clear out the internal state,
            // listeners and observers
            mViewPager = null;
            setPagerAdapter(null, false);
        }

        mSetupViewPagerImplicitly = implicitSetup;
    }

在調用setupWithViewPager會調用到setPagerAdapter(null, false)看下這個方法里發(fā)生了什么吧。

void setPagerAdapter(@Nullable final PagerAdapter adapter, final boolean addObserver) {
        if (mPagerAdapter != null && mPagerAdapterObserver != null) {
            // If we already have a PagerAdapter, unregister our observer
            mPagerAdapter.unregisterDataSetObserver(mPagerAdapterObserver);
        }

        mPagerAdapter = adapter;

        if (addObserver && adapter != null) {
            // Register our observer on the new adapter
            if (mPagerAdapterObserver == null) {
                mPagerAdapterObserver = new PagerAdapterObserver();
            }
            adapter.registerDataSetObserver(mPagerAdapterObserver);
        }

        // Finally make sure we reflect the new adapter
        populateFromPagerAdapter();
    }

setPagerAdapter里又調用了populateFromPagerAdapter(),點開這個方法:

void populateFromPagerAdapter() {
        removeAllTabs();

        if (mPagerAdapter != null) {
            final int adapterCount = mPagerAdapter.getCount();
            for (int i = 0; i < adapterCount; i++) {
                addTab(newTab().setText(mPagerAdapter.getPageTitle(i)), false);
            }

            // Make sure we reflect the currently set ViewPager item
            if (mViewPager != null && adapterCount > 0) {
                final int curItem = mViewPager.getCurrentItem();
                if (curItem != getSelectedTabPosition() && curItem < getTabCount()) {
                    selectTab(getTabAt(curItem));
                }
            }
        }
    }

這個populateFromPagerAdapter()方法里將tabLayout里所有的tab移除了喧笔,又重新new了tab帽驯。所以原來add的tab沒有顯示,那怎么解決呢书闸?再仔細看這個方法尼变,對沒錯,addTab(newTab().setText(mPagerAdapter.getPageTitle(i)), false);在重新new tab的過程中有重新傳title浆劲,這個值是通過mPagerAdapter.getPageTitle(i))獲取的嫌术,那么我們在ViewPagerFragmentPagerAdapter重寫getPageTitle方法哀澈,默認的PagerAdapter返回的是null。

public CharSequence getPageTitle(int position) {
   return null;
}

現(xiàn)在我們把代碼修改成下面的樣子:

private void initViews() {
        viewPager.setAdapter(new FragmentPagerAdapter(getSupportFragmentManager()) {
            @Override
            public Fragment getItem(int position) {
                return fragments.get(position);
            }

            @Override
            public int getCount() {
                return fragments == null ? 0 : fragments.size();
            }

            @Override
            public CharSequence getPageTitle(int position) {
                return titles.get(position);
            }
        });
        tabLayout.setupWithViewPager(viewPager);
    }

O(∩_∩)O哈哈~現(xiàn)在就是我們想要的樣子啦度气。割按。。我寫的Demo源碼

參考資料

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末磷籍,一起剝皮案震驚了整個濱河市适荣,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌择示,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,546評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件晒旅,死亡現(xiàn)場離奇詭異栅盲,居然都是意外死亡,警方通過查閱死者的電腦和手機废恋,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,224評論 3 395
  • 文/潘曉璐 我一進店門谈秫,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人鱼鼓,你說我怎么就攤上這事拟烫。” “怎么了迄本?”我有些...
    開封第一講書人閱讀 164,911評論 0 354
  • 文/不壞的土叔 我叫張陵硕淑,是天一觀的道長。 經(jīng)常有香客問我嘉赎,道長置媳,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,737評論 1 294
  • 正文 為了忘掉前任公条,我火速辦了婚禮拇囊,結果婚禮上,老公的妹妹穿的比我還像新娘靶橱。我一直安慰自己寥袭,他們只是感情好,可當我...
    茶點故事閱讀 67,753評論 6 392
  • 文/花漫 我一把揭開白布关霸。 她就那樣靜靜地躺著传黄,像睡著了一般。 火紅的嫁衣襯著肌膚如雪队寇。 梳的紋絲不亂的頭發(fā)上尝江,一...
    開封第一講書人閱讀 51,598評論 1 305
  • 那天,我揣著相機與錄音英上,去河邊找鬼炭序。 笑死啤覆,一個胖子當著我的面吹牛,可吹牛的內容都是我干的惭聂。 我是一名探鬼主播窗声,決...
    沈念sama閱讀 40,338評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼辜纲!你這毒婦竟也來了笨觅?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 39,249評論 0 276
  • 序言:老撾萬榮一對情侶失蹤耕腾,失蹤者是張志新(化名)和其女友劉穎见剩,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體扫俺,經(jīng)...
    沈念sama閱讀 45,696評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡苍苞,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,888評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了狼纬。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片羹呵。...
    茶點故事閱讀 40,013評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖疗琉,靈堂內的尸體忽然破棺而出冈欢,到底是詐尸還是另有隱情,我是刑警寧澤盈简,帶...
    沈念sama閱讀 35,731評論 5 346
  • 正文 年R本政府宣布凑耻,位于F島的核電站,受9級特大地震影響柠贤,放射性物質發(fā)生泄漏拳话。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,348評論 3 330
  • 文/蒙蒙 一种吸、第九天 我趴在偏房一處隱蔽的房頂上張望弃衍。 院中可真熱鬧,春花似錦坚俗、人聲如沸镜盯。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,929評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽速缆。三九已至,卻和暖如春恩闻,著一層夾襖步出監(jiān)牢的瞬間艺糜,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,048評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留破停,地道東北人翅楼。 一個月前我還...
    沈念sama閱讀 48,203評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像真慢,于是被迫代替她去往敵國和親毅臊。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,960評論 2 355

推薦閱讀更多精彩內容