Android Design Support Library made our day easier by providing backward compatibility to number of material design components all the way back to Android 2.1. In Design support Library the components like navigation drawer, floating action button, snackbar, tabs, floating labels and animation frameworks were introduced. In this article we are going to learn how to implement material swiping tabs in your apps.
- Tabs enable content organization at a high level, such as switching between views, data sets, or functional aspects of an app.
- Present tabs as a single row above their associated content. Tab labels should succinctly describe the content within.
- Because swipe gestures are used for navigating between tabs, don't pair tabs with content that also supports swiping.
Before going further, I suggest have a look at this tabs docs that specifies the practices to be followed while implementing tabs.
Applying the App Material design
Applying the App Material design
We’ll start this by creating a new project and applying the material theme.
1. In Android Studio, go to File -> New Project and fill all the details required to create a new project. When it prompts to select a default activity, select Blank Activity and proceed.
2. Open build.gradle and add android design support library com.android.support:design:23.2.1
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7\`23.2.1'
compile 'com.android.support:design:23.2.1'
compile 'com.google.android.gms:play-services-appindexing:8.1.0'
compile 'com.android.support:support-v4:23.2.1'
}
Open colors.xml located under res -> values and add the below color values. <resources>
<color name="colorPrimary">#C62828</color>
<color name="colorPrimaryDark">#B71C1C</color>
<color name="textColorPrimary">#FFFFFF</color>
<color name="windowBackground">#FFFFFF</color>
<color name="navigationBarColor">#000000</color>
<color ;name="colorAccent">#c8e8ff</color>
</resources>
Add the below dimensions to dimens.xml located under res -> values.<resources>
<!-- Default screen margins, per the Android Design guidelines. -->
<dimen name="activity_horizontal_margin">16dp</dimen>
<dimen name="activity_vertical_margin">16dp</dimen>
<dimen name="tab_max_width">264dp</dimen>
<dimen name="tab_padding_bottom">16dp</dimen>
<dimen name="tab_label">14sp</dimen>
<dimen name="custom_tab_layout_height">72dp</dimen>
</resources>
Open styles.xml located res -> values and add below styles. The styles defined in this styles.xml are common to all the android versions.
<resources>
<!-- Base application theme. -->
<style name="MaterialTheme" parent="MyMaterialTheme.Base">
</style>
<style name="MaterialTheme.Base" parent="Theme.AppCompat.Light.DarkActionBar">
<item name="windowNoTitle">true</item>
<item name="windowActionBar">false</item>
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
</style>
<style name="AppTheme.AppBarOverlay" parent="ThemeOverlay.AppCompat.Dark.ActionBar" />
<style name="AppTheme.PopupOverlay" parent="ThemeOverlay.AppCompat.Light" />
</resources>
Finally open AndroidManifest.xml and modify the theme to our customized theme by changing theandroid:theme attribute value.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="androidgreeve.android.com.quora_red">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/MaterialTheme" >
<activity
android:name=".MainActivity"
android:label="@string/app_name"
android:theme="@style/MaterialTheme" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity><!-- ATTENTION: This was auto-generated to add Google Play services to your project for
App Indexing. See https://g.co/AppIndexing/AndroidStudio for more information. -->
<meta-data
android:name="com.google.android.gms.version"
android:value="@integer/google_play_services_version" />
</application>
</manifest>
Run the app and verify the material theme by observing the notification bar color. If you see the notification bar color changed, it means that the material design theme is applied successfully😁.
Now we have our app material ready. So let’s start adding the tabs. But before that we’ll create few fragment activities for testing purpose. All these fragment activities contains very simple UI with only one TextView.Under your main package create a fragment named Fragment_Feed.java and add the below code.
package androidgreeve.android.com.quora_red;
import android.content.Context;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
/**
* A simple {@link Fragment} subclass.
* Activities that contain this fragment must implement the
* {@link home.OnFragmentInteractionListener} interface
* to handle interaction events.
* Use the {@link home#newInstance} factory method to
* create an instance of this fragment.
*/
public class Fragment_Feed extends Fragment {
// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";
// TODO: Rename and change types of parameters
private String mParam1;
private String mParam2;
private OnFragmentInteractionListener mListener;
public home() {
// Required empty public constructor
}
/**
* Use this factory method to create a new instance of
* this fragment using the provided parameters.
*
* @param param1 Parameter 1.
* @param param2 Parameter 2.
* @return A new instance of fragment home.
*/
// TODO: Rename and change types and number of parameters
public static home newInstance(String param1, String param2) {
home fragment = new home();
Bundle args = new Bundle();
args.putString(ARG_PARAM1, param1);
args.putString(ARG_PARAM2, param2);
fragment.setArguments(args);
return fragment;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mParam1 = getArguments().getString(ARG_PARAM1);
mParam2 = getArguments().getString(ARG_PARAM2);
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_home, container, false);
}
// TODO: Rename method, update argument and hook method into UI event
public void onButtonPressed(Uri uri) {
if (mListener != null) {
mListener.onFragmentInteraction(uri);
}
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof OnFragmentInteractionListener) {
mListener = (OnFragmentInteractionListener) context;
} else {
throw new RuntimeException(context.toString()
+ " must implement OnFragmentInteractionListener");
}
}
@Override
public void onDetach() {
super.onDetach();
mListener = null;
}
/**
* This interface must be implemented by activities that contain this
* fragment to allow an interaction in this fragment to be communicated
* to the activity and potentially other fragments contained in that
* activity.
* <p/>
* See the Android Training lesson <a href=
* "http://developer.android.com/training/basics/fragments/communicating.html"
* >Communicating with Other Fragments</a> for more information.
*/
public interface OnFragmentInteractionListener {
// TODO: Update argument type and name
void onFragmentInteraction(Uri uri);
}
}
Likewise create few more fragment activities with same code we used for Fragment_Trending.java and Fragment_Bookmark.java
Implementing Fixed Tabs:
Fixed tabs should be used when you have limited number of tabs. These tabs are fixed in position. In android design support library lot of new elements like CoordinatorLayout, AppBarLayout, TabLayout and lot more were introduced. I won’t cover all of these as it’s not the agenda of this article.
Open the layout file of main activity (activity_main.xml) and add below layout code.
app:tabMode – Defines the mode of the tab layout. In our case the value should be “fixed”
Other Tabs Options:
The scrollable tabs can be used many number of tabs where there is insufficient space on the screen to fit all of them. To make the tabs scrollable, set app:tabMode=”scrollable” to TabLayout.To Align the tabs at center
If you want to keep your tabs horizontally centered, assign app:tabGravity=”center” to TabLayout.
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:layout_scrollFlags="scroll|enterAlways"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />
<android.support.design.widget.TabLayout
android:id="@+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabMode="fixed"
app:tabGravity="fill"/>
</android.support.design.widget.AppBarLayout>
<android.support.v4.view.ViewPager
android:id="@+id/viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
</android.support.design.widget.CoordinatorLayout>
Create ViewPagerAdapter.java
package androidgreeve.android.com.quora_red;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import java.util.ArrayList;
/**
* Created by venkatesh on 29-05-2016.
*/
public class ViewPageAdapter extends FragmentPagerAdapter {
ArrayList<Fragment> fragments= new ArrayList<>();
ArrayList<String> tabtitles = new ArrayList<>();
public void addFragments(Fragment fragments,String titles)
{
this.fragments.add(fragments);
this.tabtitles.add(titles);
}
public ViewPageAdapter(FragmentManager fm)
{
super(fm);
}
@Override
public Fragment getItem(int position) {
return fragments.get(position);
}
@Override
public int getCount() {
return fragments.size();
}
public CharSequence getPageTtle(int position)
{
return tabtitles.get(position);
}
}
Open MainActivity.java and do the below changes.
tabLayout.setupWithViewPager() – Assigns the ViewPager to TabLayout.
setupViewPager() – Defines the number of tabs by setting appropriate fragment and tab name.
ViewPagerAdapter – Custom adapter class provides fragments required for the view pager.package androidgreeve.android.com.quora_red;
import android.net.Uri;
import android.os.Bundle;
import android.support.design.widget.CoordinatorLayout;
import android.support.design.widget.Snackbar;
import android.support.design.widget.TabLayout;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import com.roughike.bottombar.BottomBar;
import com.roughike.bottombar.OnMenuTabSelectedListener;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity implements home.OnFragmentInteractionListener,top_paid_fragment.OnFragmentInteractionListener,Top_free.OnFragmentInteractionListener{
private Toolbar toolbar;
private TabLayout tabLayout;
private ViewPager viewPager;
private CoordinatorLayout coordinatorLayout;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
// getSupportActionBar().setDisplayHomeAsUpEnabled(true);
viewPager = (ViewPager) findViewById(R.id.viewpager);
setupViewPager(viewPager);
tabLayout = (TabLayout) findViewById(R.id.tabs);
tabLayout.setupWithViewPager(viewPager);
coordinatorLayout = (CoordinatorLayout) findViewById(R.id.three_buttons_activity);
// Set the color for the active tab. Ignored on mobile when there are more than three tabs.
bottomBar.setActiveTabColor("#C2185B");
// Use the dark theme. Ignored on mobile when there are more than three tabs.
//bottomBar.useDarkTheme(true);
// Use custom text appearance in tab titles.
//bottomBar.setTextAppearance(R.style.MyTextAppearance);
// Use custom typeface that's located at the "/src/main/assets" directory. If using with
// custom text appearance, set the text appearance first.
//bottomBar.setTypeFace("MyFont.ttf");
}
private void setupViewPager(ViewPager viewPager) {
ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager());
adapter.addFragment(new home(), "FEED");
adapter.addFragment(new top_paid_fragment(), "TRENDING");
adapter.addFragment(new Top_free(), "BOOKMARK");
viewPager.setAdapter(adapter);
}
@Override
public void onFragmentInteraction(Uri uri) {
}
Running the App
Run the App to see the Material tabs.
EmoticonEmoticon