在Fragment中使用TabLayout;选项卡文本不可见

22

我目前正在尝试使用新的Android Support Design库中的各种新组件。我已经在我的MainActivity.java中实现了一个NavigationView,使用FragmentManager在导航抽屉中的项目之间进行导航:

getSupportFragmentManager()
    .beginTransaction()
    .replace(R.id.content, mTabLayoutFragment)
    .setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
    .commit();

我在一个碎片中使用了 TabLayout。下面是该碎片的布局:

<android.support.design.widget.AppBarLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <android.support.design.widget.TabLayout
        android:id="@+id/tabLayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:tabMode="fixed"
        app:tabGravity="fill"
        app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"/>

    <android.support.v4.view.ViewPager
        android:id="@+id/viewpager"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@android:color/white"/>

</android.support.design.widget.AppBarLayout>

而其背后的 Java 代码为:

import android.os.Bundle;
import android.support.design.widget.*;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter;
import android.support.v4.view.ViewPager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

public class TabLayoutFragment extends Fragment {   


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View inflatedView = inflater.inflate(R.layout.fragment_tablayout, container, false);

        TabLayout tabLayout = (TabLayout) inflatedView.findViewById(R.id.tabLayout);
        tabLayout.addTab(tabLayout.newTab().setText("Campusplan"));
        tabLayout.addTab(tabLayout.newTab().setText("Raumplan"));
        final ViewPager viewPager = (ViewPager) inflatedView.findViewById(R.id.viewpager);

        viewPager.setAdapter(new PagerAdapter
                (getFragmentManager(), tabLayout.getTabCount()));
        viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
        tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
            @Override
            public void onTabSelected(TabLayout.Tab tab) {
                viewPager.setCurrentItem(tab.getPosition());
            }

            @Override
            public void onTabUnselected(TabLayout.Tab tab) {

            }

            @Override
            public void onTabReselected(TabLayout.Tab tab) {

            }
        });

        return inflatedView;
    }

    public class PagerAdapter extends FragmentStatePagerAdapter {
        int mNumOfTabs;

        public PagerAdapter(FragmentManager fm, int NumOfTabs) {
            super(fm);
            this.mNumOfTabs = NumOfTabs;
        }

        @Override
        public Fragment getItem(int position) {

            switch (position) {
                case 0:
                    TabItem1 tab1 = new TabItem1();
                    return tab1;
                case 1:
                    TabItem1 tab2 = new TabItem1();
                    return tab2;
                default:
                    return null;
            }
        }

        @Override
        public int getCount() {
            return mNumOfTabs;
        }
    }
}

请注意 TabItem1TabItem1,它们是由仅包含 TextView 的片段构成。这两个片段将显示在 TabLayout 中。
现在,这段代码似乎在某种程度上是有效的。它看起来像这样: 奇怪的是,在我旋转设备后,一切似乎都正常工作: enter image description here 似乎在配置更改时会调用某些东西。这很奇怪,特别是考虑到我的 AndroidManifest 中有以下内容:
android:configChanges="orientation|screenSize"

2
更新: 这是由于设计库22.2.1中的一个错误导致的。使用23.0.0可以解决这个问题。 - J.G.Sebring
5个回答

35

我遇到了与Android支持库Design Library v23.1.1新版本相关的相同问题。但是我已经找出了发生了什么。

如果你的视图页面有两个片段,就像你上面提到的那样,那么你可以使用以下语句设置你的视图页面:

tabLayout.setupWithViewPager(viewPager);

自动地,你将会有2个空文本的标签页。所以你不应该再添加新的标签页了。不过,你需要做的是在这两个已创建的标签页中设置文本。

tabLayout.getTabAt(0).setText("Campusplan");
tabLayout.getTabAt(1).setText("Raumplan");

结论:要让选项卡按照您的意愿工作,重要的事情是您必须做到:

tabLayout.setupWithViewPager(viewPager);
tabLayout.getTabAt(0).setText("Campusplan");
tabLayout.getTabAt(1).setText("Raumplan");

我希望这对您有所帮助 :)


1
这对我来说是正确的答案。如上所述,适用于支持Design Library 23.1.1。谢谢:) - Karol Żygłowicz
但为什么这不起作用呢?tabLayout.addTab(tabLayout.newTab().setText("校园地图")); tabLayout.addTab(tabLayout.newTab().setText("房间平面图")); - abh22ishek
1
据我所知,就像上面所解释的一样。当您在tabLayout中设置viewpager时,tablayout会根据您拥有的viewpager的片段数量自动添加许多选项卡。因此,当您使用以下语句: tabLayout.addTab(tabLayout.newTab().setText("Campusplan"));您将添加一个新的带有空片段的选项卡。请及时指正。 - arif ardiansyah

19

1
现在选项卡看起来没问题了,但有时当我在导航抽屉项之间切换时,这个 TabLayout 的内部片段会消失。你的代码放在 Github 上可以看一下吗? - Mario Velasco
8
谢谢,我之前使用的是 getActivity().getSupportFragment() 而不是 getChildFragmentManager() - Mario Velasco
编译设计库v23.0.1时,出现Gradle执行错误,但是代码解决方法运行良好,感谢。 - Adam Varhegyi
2
如果我们的TabLayout附加到Toolbar,是否建议将ViewPager放在AppBarLayout中,或者无论您在xml布局中放置viewpager在哪里都没有关系? - iBobb

5

我刚刚尝试覆盖适配器中的方法:

public CharSequence getPageTitle(int position) {}

它成功了。


2

这个库的开发者建议采用以下解决方案:

if (ViewCompat.isLaidOut(tabLayout)) {
        tabLayout.setupWithViewPager(viewPager);
    } else {
        tabLayout.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
            @Override
            public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
                tabLayout.setupWithViewPager(viewPager);
                tabLayout.removeOnLayoutChangeListener(this);
            }
        });
    }

1

缺乏声誉无法评论@arif ardiansyah...

检查源代码:

 `TabLayout#setupWithViewPager(...)` 

 -->>`setPagerAdapter(adapter, true);`

 -->>`populateFromPagerAdapter();`

在这里,TabLayout会移除所有选项卡并重新创建一些新的选项卡,它们的文本是使用PagerAdapter#getPageTitle(...)设置的。因此,您可以重写此方法来提供您选项卡的标题给Tablayout

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接