Search code examples
javaandroidandroid-tablayoutmaterial-componentsmaterial-components-android

Tabs titles on TabLayout not showing


Update: I modified my adapter class to the following, and it works fine now:

public class SectionsPagerAdapter extends FragmentPagerAdapter {
R.string.tab_text_2, R.string.tab_text_3};
    //private final Context mContext;
    private static int tab_count;
    private Context mContext;

    public SectionsPagerAdapter(FragmentManager fm, int tab_count, Context context) {
        super(fm);
        mContext = context;
        this.tab_count = tab_count;
    }

    @Override
    public Fragment getItem(int position) {
        // getItem is called to instantiate the fragment for the given page.
        // Return a PlaceholderFragment (defined as a static inner class below).
        //return PlaceholderFragment.newInstance(position + 1);
        switch (position)
        {
            case 0:
                Tab1Pagina_Inicial tab1 = new Tab1Pagina_Inicial();
                return tab1;

            case 1:
                Tab2Apartamentos tab2 = new Tab2Apartamentos();
                return tab2;

            case 2:
                Tab3ItensDeApartamentos tab3 = new Tab3ItensDeApartamentos();
                return tab3;

             default:
                 return null;
        }
    }

    @Override
    public CharSequence getPageTitle(int position) {
        switch (position)
        {
            case 0:
                return mContext.getString(R.string.tab_text_1);
            case 1:
                return mContext.getString(R.string.tab_text_2);
            case 2:
                return mContext.getString(R.string.tab_text_3);
            default:
                return null;
        }
    }

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

Adding the getPageTitle worked! Thank you for the tips. ^^

I'm creating an app with a tab menu but the tabs' titles are not displaying properly. I've tried rereading and looking again at every tutorial I've seen so far, as well as comparing my code to others with similar questions here on stackoverflow but I still can't seem to identify what I'm doing wrong and where. Could anyone enlighten me as to my mistake?

Thank you in advance for any clarification.

Edit: I don't think it's the color. I've tried messing with the colors and themes of both TabLayout, AppBarLayout and each tab item separately (as well as removing the themes altogether) and the titles are still not showing like they should. But I'll post the code for my colors.xml and styles.xml files just in case.

Edit 2: Guys, I've found out something curious. Now I'm not sure I really understand TabLayout as I thought I did. Before I set my TabLayout with my ViewPager with the setupWithViewPager method, everything appears as it should. The titles show up I mean. But I can only actually change tabs by swiping. Clicking on each tab does nothing. I'll attach an image to show what I mean.

Here's what I thought I understood: I know I need an adapter to render each fragment as content for each tab. I know the ViewPager is the component responsible for the swiping between tabs. TabLayout is a layout where I can display my tabs. I need to hook my TabLayout to my ViewPager in order to display the correct content whenever I click a specific tab.

Am I missing something?

MainActivity:

package com.example.pousadaviladascores.Activities;

import androidx.appcompat.app.AppCompatActivity;
import androidx.viewpager.widget.ViewPager;
import android.os.Bundle;
import com.example.pousadaviladascores.DAO.SqlAccess;
import com.example.pousadaviladascores.UI.SectionsPagerAdapter;
import com.example.pousadaviladascores.R;
import com.google.android.material.tabs.TabLayout;

public class MainActivity extends AppCompatActivity {

    SqlAccess sqlAccess;

    //Declaring TabLayout and ViewPager
    TabLayout tabLayout;
    ViewPager viewPager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        getSupportActionBar().hide();
        setContentView(R.layout.activity_main);

        sqlAccess = new SqlAccess(this);

        //Initializing TabLayout
        tabLayout = findViewById(R.id.tabLayout);

        //Initializing viewPager
        viewPager = findViewById(R.id.view_pager);

        //Initializing page adapter
        //OBS: In Android, Adapter is a bridge between UI component and data source that helps us to fill data in UI component.
        SectionsPagerAdapter sectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager(), tabLayout.getTabCount());

        //Sets a PagerAdapter that will supply views for this pager as needed
        viewPager.setAdapter(sectionsPagerAdapter);

        tabLayout.setupWithViewPager(viewPager);

    }

    @Override
    protected void onDestroy() {
        sqlAccess.getDbHelper().close();
        super.onDestroy();
    }
}

Fragment class (I have three classes, one for each fragment and they all have the same code, so I'm just posting one):

package com.example.pousadaviladascores.Activities;

import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import androidx.fragment.app.Fragment;

import com.example.pousadaviladascores.R;

public class Tab1Pagina_Inicial extends Fragment {

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
    {
        return inflater.inflate(R.layout.tab1_fragment_pagina_inicial, container, false);
    }
}

Page Adapter class:

package com.example.pousadaviladascores.UI;

import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentPagerAdapter;

import com.example.pousadaviladascores.Activities.Tab1Pagina_Inicial;
import com.example.pousadaviladascores.Activities.Tab2Apartamentos;
import com.example.pousadaviladascores.Activities.Tab3ItensDeApartamentos;

/**
 * A [FragmentPagerAdapter] that returns a fragment corresponding to
 * one of the sections/tabs/pages.
 */
public class SectionsPagerAdapter extends FragmentPagerAdapter {

    private static int tab_count;

    public SectionsPagerAdapter(FragmentManager fm, int tab_count) {
        super(fm);
        //mContext = context;
        this.tab_count = tab_count;
    }

    @Override
    public Fragment getItem(int position) {
        switch (position)
        {
            case 0:
                Tab1Pagina_Inicial tab1 = new Tab1Pagina_Inicial();
                return tab1;

            case 1:
                Tab2Apartamentos tab2 = new Tab2Apartamentos();
                return tab2;

            case 2:
                Tab3ItensDeApartamentos tab3 = new Tab3ItensDeApartamentos();
                return tab3;

             default:
                 return null;
        }
    }

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

activity_main.xml:

<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout 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">

    <com.google.android.material.appbar.AppBarLayout
        android:id="@+id/appBarLayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/AppTheme.AppBarOverlay">

        <TextView
            android:id="@+id/textViewAppName"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:paddingLeft="20dp"
            android:paddingTop="5dp"
            android:paddingRight="20dp"
            android:text="@string/pousada_name"
            android:textSize="24sp" />

        <androidx.appcompat.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="34dp"
            android:theme="?attr/actionBarTheme"
            app:layout_scrollFlags="scroll|enterAlways" />

        <com.google.android.material.tabs.TabLayout
            android:id="@+id/tabLayout"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:tabMode="fixed">

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

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

            <com.google.android.material.tabs.TabItem
                android:id="@+id/tab3"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@string/tab_text_3" />
        </com.google.android.material.tabs.TabLayout>
    </com.google.android.material.appbar.AppBarLayout>

    <androidx.viewpager.widget.ViewPager
        android:id="@+id/view_pager"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_behavior="@string/appbar_scrolling_view_behavior" />

</androidx.coordinatorlayout.widget.CoordinatorLayout>

Tab layout (again, all the same except for the text):

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <TextView
        android:id="@+id/textTab"
        android:layout_width="369dp"
        android:layout_height="54dp"
        android:layout_alignParentStart="true"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:layout_alignParentEnd="true"
        android:layout_marginStart="27dp"
        android:layout_marginLeft="27dp"
        android:layout_marginTop="0dp"
        android:layout_marginEnd="15dp"
        android:text="@string/tab_text_1"
        android:textSize="30sp"
        android:layout_alignParentRight="true"
        android:layout_marginRight="15dp" />

</RelativeLayout>

colors.xml:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="colorPrimary">#008577</color>
    <color name="colorPrimaryDark">#00574B</color>
    <color name="colorAccent">#D81B60</color>
</resources>

styles.xml:

<resources>

    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
    </style>

    <style name="AppTheme.NoActionBar">
        <item name="windowActionBar">false</item>
        <item name="windowNoTitle">true</item>
    </style>

    <style name="AppTheme.AppBarOverlay" parent="ThemeOverlay.AppCompat.Dark.ActionBar" />

    <style name="AppTheme.PopupOverlay" parent="ThemeOverlay.AppCompat.Light" />

</resources>

To better illustrate what I mean, here's the design of activity_main and how it's supposed to look:

Here's what's actually happening: enter image description here

enter image description here enter image description here

The text for each page shows up fine, but not the titles. :/


Solution

  • Activity main

    <?xml version="1.0" encoding="utf-8"?>
    <androidx.coordinatorlayout.widget.CoordinatorLayout 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">
    
        <com.google.android.material.appbar.AppBarLayout
            android:id="@+id/appBarLayout"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:theme="@style/AppTheme.AppBarOverlay">
    
            <TextView
                android:id="@+id/textViewAppName"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:paddingLeft="20dp"
                android:paddingTop="5dp"
                android:paddingRight="20dp"
                android:text="@string/pousada_name"
                android:textSize="24sp" />
    
            <androidx.appcompat.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="34dp"
                android:theme="?attr/actionBarTheme"
                app:layout_scrollFlags="scroll|enterAlways" />
    
            <com.google.android.material.tabs.TabLayout
                android:id="@+id/tabLayout"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                app:tabMode="fixed"
                app:tabGravity="fill"/>
        </com.google.android.material.appbar.AppBarLayout>
    
        <androidx.viewpager.widget.ViewPager
            android:id="@+id/view_pager"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:layout_behavior="@string/appbar_scrolling_view_behavior" />
    
    </androidx.coordinatorlayout.widget.CoordinatorLayout>
    

    Your main activity

    public class MainActivity extends AppCompatActivity {
    
        SqlAccess sqlAccess;
    
        //Declaring TabLayout and ViewPager
        TabLayout tabLayout;
        ViewPager viewPager;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            getSupportActionBar().hide();
            setContentView(R.layout.activity_main);
    
            sqlAccess = new SqlAccess(this);
    
            viewPager = (ViewPager) findViewById(R.id.view_pager);
            setupViewPager(viewPager);
    
            tabLayout = (TabLayout) findViewById(R.id.tabLayout);
            tabLayout.setupWithViewPager(viewPager);
    
        }
     private void setupViewPager(ViewPager viewPager) {
            SectionsPagerAdapter adapter = new SectionsPagerAdapter(getSupportFragmentManager());
            adapter.addFragment(new Tab1Pagina_Inicial(), "ONE");
            adapter.addFragment(new Tab2Apartamentos(), "TWO");
            adapter.addFragment(new Tab3ItensDeApartamentos(), "THREE");
            viewPager.setAdapter(adapter);
        }
    
        @Override
        protected void onDestroy() {
            sqlAccess.getDbHelper().close();
            super.onDestroy();
        }
    }
    

    And replace your section pager adapter with this

    class SectionPagerAdapter extends FragmentPagerAdapter {
            private final List<Fragment> mFragmentList = new ArrayList<>();
            private final List<String> mFragmentTitleList = new ArrayList<>();
    
            public SectionPagerAdapter(FragmentManager manager) {
                super(manager);
            }
    
            @Override
            public Fragment getItem(int position) {
                return mFragmentList.get(position);
            }
    
            @Override
            public int getCount() {
                return mFragmentList.size();
            }
    
            public void addFragment(Fragment fragment, String title) {
                mFragmentList.add(fragment);
                mFragmentTitleList.add(title);
            }
    
            @Override
            public CharSequence getPageTitle(int position) {
                return mFragmentTitleList.get(position);
            }
        }