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).
![](https://1.bp.blogspot.com/-liraQhLEn60/VWihbiaXaJI/AAAAAAAABvQ/nKi1_xcx6yk/s1600/tabs.png)
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.