1

I've started to change from using ActionBarActivity to AppCompatActivity, but I've also started using the Toolbar as well instead of a standard ActionBar.

However, in one of my activities which has a swiping tab type of layout, the following line seems to be deprecated:

actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);

Although I have looked at some other answers on Stack Overflow regarding this, is there any built-in way of changing this to support using the Toolbar. If so, could you explain exactly how I would go about changing it? How would deprecated methods like onTabSelected be changed?

Also, I've noticed that the Google Play Music app has what looks like an extended toolbar/section underneath the tabs (see this image for what I am talking about). How would I be able to have that type of layout?

Thanks in advance.

Farbod Salamat-Zadeh
  • 19,687
  • 20
  • 75
  • 125
  • for sliding tab use https://developer.android.com/samples/SlidingTabsBasic/project.html – N J Apr 25 '15 at 17:14
  • I've had a look at the code, but I'm not sure exactly how it works. – Farbod Salamat-Zadeh Apr 25 '15 at 17:20
  • http://stackoverflow.com/questions/26540078/use-tab-with-new-toolbar-appcompat-v7-21/26543020#26543020 – Gabriele Mariotti Apr 26 '15 at 07:57
  • As I said, I've had a look at the code, but there are a lot of Java files and layout files. How exactly does it work? – Farbod Salamat-Zadeh Apr 26 '15 at 08:55
  • @GabrieleMariotti I managed to add in the code from the SlidingTabsBasic sample, but this does not give me the layout I want. I've added it in, and the tabs are separate from the toolbar, and are grey, with a thick borderline. I want a layout something more like [this](http://cdn.makeuseof.com/wp-content/uploads/2015/03/MaterialDesignMusicPlayer-Play-Music.jpg?6055c3) (on the left side). As you can see, in that image, the tabs are connected to the toolbar and look part of it. I also like the orange extended part that drops below the tabs but I wouldn't mind not having that. – Farbod Salamat-Zadeh Apr 26 '15 at 10:00

1 Answers1

14

So after a few days of lots of research, and looking through GitHub, I finally managed to solve my problem.

Steps to updating the ActionBar tabs to Toolbar tabs using AppCompatActivity:


UPDATE: After Friday 29th May 2015:

Thankfully, using a TabLayout with the Toolbar has become much simpler since the announcement of the Android Design Support Library in Google I/O 2015.
We no longer need to download custom view classes, and this is something Google really should have done a long time ago.

From the Android Developers' Blogspot post on the Android Design Support Library:

Tabs:

Switching between different views in your app via tabs is not a new concept to material design and they are equally at home as a top level navigation pattern or for organizing different groupings of content within your app (say, different genres of music).

The Design library’s TabLayout implements both fixed tabs, where the view’s width is divided equally between all of the tabs, as well as scrollable tabs, where the tabs are not a uniform size and can scroll horizontally. Tabs can be added programmatically:

TabLayout tabLayout = ...;
tabLayout.addTab(tabLayout.newTab().setText("Tab 1"));

However, if you are using a ViewPager for horizontal paging between tabs, you can create tabs directly from your PagerAdapter’s getPageTitle() and then connect the two together using setupWithViewPager(). This ensures that tab selection events update the ViewPager and page changes update the selected tab.


Prior to Google I/O 2015:

Firstly, I downloaded the SlidingTabLayout.java and SlidingTabStrip.java files from Google's I/O Conference app on GitHub. These would be the views that would be used in the tab layout, so I created a folder with my other Java activities called 'view' and placed them there.

Next, I edited my activity layout .xml to look a bit like this:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:ads="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="com.mycompany.myapp.MyActivity" >

    <!-- This is the Toolbar with the tabs underneath -->
    <LinearLayout android:id="@+id/detail_headerBar"
        style="@style/HeaderBar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">

        <include android:id="@+id/detail_toolbar" layout="@layout/toolbar" />

        <com.mycompany.myapp.view.SlidingTabLayout
            android:id="@+id/sliding_tabs"
            android:background="?attr/colorPrimary"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />
    </LinearLayout>

    <!-- This is the ViewPager (which I had used before) and 
         it would be responsible for the swiping to change layouts -->
    <android.support.v4.view.ViewPager
        android:id="@+id/view_pager"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@id/detail_headerBar"
        android:layout_above="@+id/detail_adView" />

    <!-- I also had an AdView in my layout,
         but this is not necessary for creating tab layouts -->
    <com.google.android.gms.ads.AdView
        android:id="@+id/detail_adView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        ads:adSize="SMART_BANNER"
        ads:adUnitId="@string/banner_ad_unit_id" >
    </com.google.android.gms.ads.AdView>

</RelativeLayout>

The line which references the Toolbar (<include android:id="@+id/detail_toolbar" layout="@layout/toolbar" />), is referencing the following layout (for those who aren't sure how to use the Toolbar yet):

<android.support.v7.widget.Toolbar
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/toolbar"
    android:layout_height="wrap_content"
    android:layout_width="match_parent"
    android:minHeight="?attr/actionBarSize"
    android:background="?attr/colorPrimary"
    app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
    app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />

And in both of the .xml layout files above, ?attr/colorPrimary, refers to the primary colour of my app (which I had defined in a style).

Also, in the first layout, the style I had mentioned as @style/HeaderBar refers to the following:

<style name="HeaderBar">
    <item name="android:background">?colorPrimary</item>
    <item name="android:elevation">4dp</item>
    <!-- You may have to override this in a v21 version of this file -->
</style>

Before I started setting up the layouts in Java, I had to make sure to change the package names in SlidingTabLayout.java and SlidingTabStrip.java corresponding to where they were placed. In my case, I used: package com.mycompany.myapp.view; in both of these files.

Now, in my Activity (which was extending AppCompatActivity), I first added the following in the onCreate method:

Toolbar toolbar = (Toolbar) findViewById(R.id.detail_toolbar);
setSupportActionBar(toolbar);

This would be reponsible for displaying the Toolbar.

Then I setup the ViewPager and SlidingTabLayout parts:

mViewPager = (ViewPager) findViewById(R.id.view_pager);
mViewPager.setAdapter(new ViewPagerAdapter(getSupportFragmentManager()));

mSlidingTabLayout = (SlidingTabLayout) findViewById(R.id.sliding_tabs);
mSlidingTabLayout.setSelectedIndicatorColors(getResources().getColor(R.color.tab_line));   
mSlidingTabLayout.setDistributeEvenly(true);
mSlidingTabLayout.setViewPager(mViewPager);

The colour 'tab_line' was a colour I had declared in color.xml which would be the colour of the tab line indicator. Also note that the variables above were global which I defined previously in this activity:

SlidingTabLayout mSlidingTabLayout;
ViewPager mViewPager;

The final thing to do was to setup the ViewPagerAdapter which I had called eariler. This would be responsible for changing the page depending on which tab was selected. I used the following:

public class ViewPagerAdapter extends FragmentPagerAdapter {

    public ViewPagerAdapter(FragmentManager fm) {
        super(fm);
    }

    @Override
    public int getCount() {
        // Returns the number of tabs
        return 3;
    }

    @Override
    public Fragment getItem(int position) {
        // Returns a new instance of the fragment
        switch (position) {
            case 0:
                return new FragmentOne();
            case 1:
                return new FragmentTwo();
            case 2:
                return new FragmentThree();
        }
        return null;
    }

    @Override
    public CharSequence getPageTitle(int position) {
        Locale l = Locale.getDefault();
        switch (position) {
            case 0:
                return getString(R.string.title_section1).toUpperCase(l);
            case 1:
                return getString(R.string.title_section2).toUpperCase(l);
            case 2:
                return getString(R.string.title_section3).toUpperCase(l);
        }
        return null;
    }
}

I hope this was a thorough enough answer for those who are having the same trouble as I did, when switching from ActionBarActivity to AppCompatActivity and starting to use Toolbar instead of ActionBar. If there is anything that is unclear, feel free to comment below.

Community
  • 1
  • 1
Farbod Salamat-Zadeh
  • 19,687
  • 20
  • 75
  • 125
  • Thanks for this, it works great for the most part. The only issue I'm running into is that I don't see any actual tabs at the top of my screen. I can scroll left and right to different viewpages, just no tabs to designate what I'm looking at. Any ideas? (I followed the code example you provided very closely) – ImDevinC May 26 '15 at 14:37
  • @TheRedAgent Hmm. Have you included the `SlidingTabLayout` in the activity layout? – Farbod Salamat-Zadeh May 26 '15 at 14:44
  • @FarbodSalamat-Zadeh: Thanks for your answer. Helps alot. But now i want to change the text of tabs at run time. How to do that? – Manoj Fegde Jul 23 '15 at 12:05
  • @ManojFegde If you are using a `ViewPager` with an adapter, specify names in the `getPageTitle` method, as described at the bottom of my answer. If you are not using a `ViewPager`, you should do `tabLayout.addTab(tabLayout.newTab().setText("Tab 1"));`, changing 'Tab 1' depending on the name you want. Details to both of these solutions are given in my answer above. – Farbod Salamat-Zadeh Jul 23 '15 at 12:09
  • I tried tabLayout.addTab(tabLayout.newTab().setText("Tab 1")); but getting error as : The method newTab() is undefined for the type SlidingTabLayout – Manoj Fegde Jul 23 '15 at 12:35
  • Just want to change text of tab at run time. – Manoj Fegde Jul 23 '15 at 12:35
  • @ManojFegde If you are using a `SlidingTabLayout`, you should not use `tabLayout.addTab(...);` because they are different things. If you are using a `SlidingTabLayout`, you should use a `ViewPager`. The second half of my answer (entitled 'Prior to Google I/O 2015'), describes everything you would need to do to use a `SlidingTabLayout`. – Farbod Salamat-Zadeh Jul 23 '15 at 12:45
  • Thanx. It works. Now one more thing that i want to change selected tab indicator color to custom from blue. – Manoj Fegde Jul 23 '15 at 14:15
  • I think you should be able to do that using `mSlidingTabLayout.setSelectedIndicatorColors(getResources.getColor(R.color.your_colour));`, where 'your_colour' is your tab indicator colour, specified in your colours XML file. – Farbod Salamat-Zadeh Jul 23 '15 at 14:19
  • page not found for SlidingTabLayout.java – John Joe Feb 19 '18 at 10:51