0

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. :/

Laila Campos
  • 801
  • 1
  • 8
  • 21

3 Answers3

1

There are 2 issues.

The method tabLayout.setupWithViewPager() removes all tabs and then adds tabs from the adapted using: addTab(newTab().setText(pagerAdapter.getPageTitle(i)), false);

You have to override in your adapter the method getPageTitle to obtain the title string. The default value is null. Something like:

@Override
public CharSequence getPageTitle(int position) {
    switch (position) {
        case 0:
            return "....";
        case 1:
            return "....";
        ....   
    }
    return null;
}

Also to use the com.google.android.material.tabs.TabLayout you have to use a Material Components Theme in your app. You are using an AppCompat theme.

You can:

  • switch to a Material Components theme (suggested and required in the next releases)
  • add app:tabTextColor attribute:
  <com.google.android.material.tabs.TabLayout
      app:tabTextColor="@color/mySelector"
      .../>
  • define the style:
  <com.google.android.material.tabs.TabLayout
      style="@style/Widget.MaterialComponents.TabLayout"

The default style used by the TabLayout in a Material Component theme is Widget.MaterialComponents.TabLayout while in an AppCompat is Widget.Design.TabLayout

There are some difference, in your case it is the issue:

<style name="Widget.Design.TabLayout" >
  <item name="tabIndicatorColor">?attr/colorAccent</item>
  <item name="tabTextColor">@null</item>
Gabriele Mariotti
  • 320,139
  • 94
  • 887
  • 841
  • I'm not sure I'm following everything, but here's what I've tried to do based on your answer: - Changing the overall app theme on styles.xml From – Laila Campos Nov 06 '19 at 17:42
  • I've tried a combination of these steps as well as all of them at the same time. So far, the only thing that changed is that the TabLayout is now white. Titles still not showing. Did I miss anything or do something wrong? – Laila Campos Nov 06 '19 at 17:42
  • @LailaCampos Updated the answer. You have to override the getPageTitle method in the adapter. In any case you should use a Material theme as described in the answer. – Gabriele Mariotti Nov 06 '19 at 20:40
0

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);
        }
    }
kam1234
  • 574
  • 2
  • 5
  • 9
  • Android studio doesn't recognize these colors variables because I didn't define them first. Could you share the code for your colors.xml file? – Laila Campos Nov 06 '19 at 01:25
  • Titles still not showing, only now the tabLayout is red (hot pink?), :/ Here's the image link: https://imgur.com/5UA0LLQ – Laila Campos Nov 06 '19 at 02:44
  • sorry, ma'am may it will help you – kam1234 Nov 06 '19 at 03:48
  • It was the getPageTitle method! Instead of adding tabs in the MainActivity class, I kept them at the layout file, but added this to the adapter: – Laila Campos Nov 09 '19 at 19:28
  • @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; } } – Laila Campos Nov 09 '19 at 19:28
  • But it seems redundant to have to pass the title twice, in this case. :/ – Laila Campos Nov 09 '19 at 19:29
  • Why are you not adding tabs in activity instead of xml? – kam1234 Nov 09 '19 at 19:32
  • Is it relevant to the project in some way? I mean, is it better to add in activity for some reason? Since one of the first tutorials I've read did it this way, I guess I just stuck with it. Am I wrong to do so? – Laila Campos Nov 10 '19 at 03:21
  • Adding tabs in activity is good for you and don't try to add every thing in xml – kam1234 Nov 10 '19 at 04:02
  • I wanted to ask what's the difference and why is one way better than the other, but this answer helped out with that: https://stackoverflow.com/a/38035415/11627241 I'll add them in my MainActivity instead. Thank you for the tip! ^^ – Laila Campos Nov 10 '19 at 08:10
0

in activity_main.xml, remove android:theme="@style/AppTheme.AppBarOverlay from appbarlayout(). i think text color problem. it is the same color as appbar. so it is not showing. if you change your theme probably your text will be appeared.

Kishan Viramgama
  • 893
  • 1
  • 11
  • 23
  • I've tried doing that and it's still doesn't show. :/ 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 and the titles are still not showing like they should. But I'll update the question and post the code for my colors.xml file just in case. – Laila Campos Nov 06 '19 at 01:32