【问题标题】:Android material TabLayout TabItem doesn't show textAndroid材料TabLayout TabItem不显示文字
【发布时间】:2021-05-23 13:26:50
【问题描述】:

我想设置一个 TabLayout。当我在 XML 中或以编程方式添加 TabItems 时,它们会占用空间并且可以单击,但不会显示它们的文本。当我通过 tab.getText() 在 OnTabSelectedListener 内以编程方式访问他们的文本时,它就在那里。
当我想使用寻呼机时,也发生了同样的情况。
我知道,那个

TabItem 实际上并没有添加到 TabLayout,它只是一个虚拟的 允许设置标签项的文本、图标和自定义布局

但我不知道如何在屏幕上显示其文本。
AndroidStudio 的设计按预期显示布局。
我用 Java 编写我的应用程序。

.xml:

<com.google.android.material.tabs.TabLayout
    android:id="@+id/exercise_menu_tabLayout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@color/colorSurfaceElevation1dp"
    app:tabMode="fixed"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintTop_toTopOf="parent">

    <com.google.android.material.tabs.TabItem
        android:id="@+id/exercise_menu_dayTabItem"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Day"/>

    <com.google.android.material.tabs.TabItem
        android:id="@+id/exercise_menu_myExercisesTabItem"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="My Exercises"/>

    <com.google.android.material.tabs.TabItem
        android:id="@+id/exercise_menu_exerciseTabItem"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Exercises"/>

</com.google.android.material.tabs.TabLayout>

它在 AndroidStudio 中的外观:
How it looks in AndroidStudio
它在应用程序中的外观:
How it looks in the app

请帮忙,材料快把我逼疯了

【问题讨论】:

  • 将这两个添加到您的 xml app:tabTextColor ="@color/white" app:tabSelectedTextColor="@color/white" 在 TabsLayout 视图中
  • @SarahKhan 很遗憾,它不起作用

标签: java android android-studio material-design material-components-android


【解决方案1】:

因为我不想将分页器与片段一起使用,而且我无法让 TabLayout 工作,所以我制作了自己的 TabLayout。
我将LinearLayout与TextViews一起使用,并在底部和适当的backgroundColor中制作了一个drawable。它完美无缺,唯一缺少的是线条移动的动画。
每次点击后,之前选择的 textView 的外观都会恢复,新的会发生变化。

<TextView
    android:id="@+id/exercise_menu_dayTextView"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:text="Day"
    android:textAlignment="center"
    android:layout_weight="1"
    android:textSize="18sp"
    android:textStyle="bold|italic"
    android:textColor="@color/textColor"
    android:background="@color/colorSurfaceElevation1dp"
    android:paddingVertical="8dp"/>

<TextView
    android:id="@+id/exercise_menu_myExercisesTextView"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:text="My Exercises"
    android:textAlignment="center"
    android:layout_weight="1"
    android:textSize="18sp"
    android:textStyle="bold|italic"
    android:textColor="?attr/colorPrimary"
    android:maxLines="1"
    android:background="@drawable/back_line_bottom"
    android:paddingVertical="8dp"/>

<TextView
    android:id="@+id/exercise_menu_exerciseTextView"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:text="Exercises"
    android:textAlignment="center"
    android:layout_weight="1"
    android:textSize="18sp"
    android:textStyle="bold|italic"
    android:textColor="@color/textColor"
    android:background="@color/colorSurfaceElevation1dp"
    android:paddingVertical="8dp"/>

back_line_bottom.xml

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <shape android:shape="rectangle">
            <solid android:color="@color/colorPrimary"/>
        </shape>
    </item>
    <item android:bottom="2dp">
        <shape android:shape="rectangle">
            <solid android:color="@color/colorSurfaceElevation1dp"/>
        </shape>
    </item>
</layer-list>

背景变化:

public void changeTypeVisually(int tabId) {
    //  Resets the background
    switch(currentTabId) {
        case 0:
            myExercisesTextView.setBackgroundColor(getResources().getColor(R.color.colorSurfaceElevation1dp));
            myExercisesTextView.setTextColor(getResources().getColor(R.color.textColor));
            break;
        case 1:
            dayTextView.setBackgroundColor(getResources().getColor(R.color.colorSurfaceElevation1dp));
            dayTextView.setTextColor(getResources().getColor(R.color.textColor));
            break;
        case 2:
            exerciseTextView.setBackgroundColor(getResources().getColor(R.color.colorSurfaceElevation1dp));
            exerciseTextView.setTextColor(getResources().getColor(R.color.textColor));
            break;
    }

    //  Adds the underline
    switch(tabId) {
        case 0:
            myExercisesTextView.setBackground(getResources().getDrawable(R.drawable.back_line_bottom));
            myExercisesTextView.setTextColor(getResources().getColor(R.color.colorPrimary));
            break;
        case 1:
            dayTextView.setBackground(getResources().getDrawable(R.drawable.back_line_bottom));
            dayTextView.setTextColor(getResources().getColor(R.color.colorPrimary));
            break;
        case 2:
            exerciseTextView.setBackground(getResources().getDrawable(R.drawable.back_line_bottom));
            exerciseTextView.setTextColor(getResources().getColor(R.color.colorPrimary));
            break;
    }
    currentTabId = tabId;
}

【讨论】:

    【解决方案2】:

    这可以通过编程解决

    第一步创建FragmentStateAdapter适配器类

    public class TabAdapter extends FragmentStateAdapter {
    
        public TabAdapter(@NonNull FragmentActivity fragmentActivity) {
            super(fragmentActivity);
        }
    
        @NonNull
        @Override
        public Fragment createFragment(int position) {
    
            switch (position) {
                case 0:
                    return new DayFragment();
                case 1:
                    return new MyExerciseFragment();
                default:
                    return new ExerciseFragment();
            }
        }
    
        @Override
        public int getItemCount() {
            return 3;
        }
    }
    
    

    第 2 步activityfragment 类中创建一个方法以使用 TabLayoutMediator 设置选项卡并在 onCreate 方法中调用该方法

    void setupTabLayout() {
            ViewPager2 viewPager = binding.exerciseMenuViewPager;
            
            viewPager.setAdapter(tabAdapter);
    
            TabLayout tabLayout = binding.exerciseMenuTabLayout;
    
            new TabLayoutMediator(tabLayout, viewPager, (tab, position) -> {
                switch (position) {
                    case 0:
                        tab.setText("Day");
                        break;
                    case 1:
                        tab.setText("My Exercise");
                        break;
                    default:
                        tab.setText("Exercise");
                }
            }).attach();
        }
    

    这就是你的活动类的样子

    public class MainActivity extends AppCompatActivity {
    
    
        private ActivityMainBinding binding;
        private TabAdapter tabAdapter;
    
        @Override
        protected void onCreate(@Nullable Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            binding = ActivityMainBinding.inflate(getLayoutInflater());
            setContentView(binding.getRoot());
    
            tabAdapter = new TabAdapter(this);
    
            setupTabLayout();
        }
    
        void setupTabLayout() {}
    }
    

    注意:要使用 ViewBinding,请将此代码添加到您的应用级别 build.gradle 文件中。

    android{
        
        ...
         buildFeatures {
            viewBinding true
        }
        ...
    }
    

    activity_main.xml

    <?xml version="1.0" encoding="utf-8"?>
    <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">
    
        <com.google.android.material.tabs.TabLayout
            android:id="@+id/exercise_menu_tabLayout"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:layout_constraintTop_toTopOf="parent" />
    
        <androidx.viewpager2.widget.ViewPager2
            android:id="@+id/exercise_menu_viewPager"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:layout_constraintTop_toBottomOf="@id/exercise_menu_tabLayout" />
    
    </androidx.constraintlayout.widget.ConstraintLayout>
    

    Final results

    PS:您需要创建这些片段类DayFragment.javaMyExerciseFragment.javaExerciseFragment

    【讨论】:

    • 您的答案可能有效,但绑定看不到 MainActivity 外部的视图。我真的不想使用片段,因为我已经编写了用于更改 RecyclerViews 的整个后端,所以我用 TextViews 和一个底部有一条线的可绘制对象制作了自己的 TabLayout。工作原理相同,只是错过了移动线动画。感谢您的宝贵时间
    • 当您启用view binding 时,所有布局文件都会生成自己的绑定类。 Read more here.
    猜你喜欢
    • 2020-08-23
    • 2022-08-04
    • 1970-01-01
    • 2015-09-18
    • 1970-01-01
    • 1970-01-01
    • 2015-07-15
    • 1970-01-01
    • 2021-01-11
    相关资源
    最近更新 更多