TabLayout
widget from Material Design, we can build this interface easily.
About previous tab design
PagerTitleStrip
or PagerTabStrip
in Android SDK or use an external library like ViewPagerIndicator. These methods have a features: always attaching the "tab widget" with a ViewPager
, and in order to make this requirement, we must disable swipe feature of the ViewPager
.
Now, with Material design, we now use TabLayout
widget, which can "stand alone" to build a tab bar and do not need a ViewPager
anymore.Sample project
activity_main.xml
Because of using <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="info.devexchanges.tabbarwithoutviewpager.MainActivity">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />
<android.support.design.widget.TabLayout
android:id="@+id/tab_layout"
style="@style/MyCustomTabLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/colorPrimary"
app:tabGravity="fill"
app:tabMode="fixed" />
<LinearLayout
android:id="@+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" />
</LinearLayout>
Toolbar
, your app theme must be a "no action bar theme". I also put a custom style for TabLayout
in styles-resource:
styles.xml
In activity programmatically code, creating tab items and handling their click event:
<resources>
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
</style>
<style name="MyCustomTabLayout" parent="Widget.Design.TabLayout">
<item name="tabTextAppearance">@style/MyCustomTabText</item>
<item name="tabSelectedTextColor">@android:color/holo_green_dark</item>
</style>
<style name="MyCustomTabText" parent="TextAppearance.AppCompat.Button">
<item name="android:textSize">14sp</item>
<item name="android:textStyle">bold</item>
<item name="android:textColor">@android:color/white</item>
</style>
</resources>
MainActivity.java
As you can see, when each tab was clicked, we'll replace corresponding
package info.devexchanges.tabbarwithoutviewpager;
import android.os.Bundle;
import android.support.design.widget.TabLayout;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.widget.LinearLayout;
public class MainActivity extends AppCompatActivity {
private TabLayout tabLayout;
private LinearLayout container;
@SuppressWarnings("ConstantConditions")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
tabLayout = (TabLayout) findViewById(R.id.tab_layout);
container = (LinearLayout) findViewById(R.id.fragment_container);
setSupportActionBar(toolbar);
//create tabs title
tabLayout.addTab(tabLayout.newTab().setText("Applications"));
tabLayout.addTab(tabLayout.newTab().setText("Books"));
tabLayout.addTab(tabLayout.newTab().setText("Games"));
//replace default fragment
replaceFragment(new ApplicationFragment());
//handling tab click event
tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
@Override
public void onTabSelected(TabLayout.Tab tab) {
if (tab.getPosition() == 0) {
replaceFragment(new ApplicationFragment());
} else if (tab.getPosition() == 1) {
replaceFragment(new BookFragment());
} else {
replaceFragment(new GameFragment());
}
}
@Override
public void onTabUnselected(TabLayout.Tab tab) {
}
@Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
}
private void replaceFragment(Fragment fragment) {
FragmentManager fragmentManager = getSupportFragmentManager();
android.support.v4.app.FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.replace(R.id.fragment_container, fragment);
transaction.commit();
}
}
Fragment
into a container layout. These are Fragments
code:
GameFragment.java
package info.devexchanges.tabbarwithoutviewpager;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import java.util.ArrayList;
public class GameFragment extends Fragment {
protected ArrayList<String> strings;
private ListView listView;
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
strings = new ArrayList<>();
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_content, container, false);
listView = (ListView) view.findViewById(R.id.list_view);
setData();
ArrayAdapter<String> adapter = new ArrayAdapter<>(getActivity(), android.R.layout.simple_list_item_1, strings);
listView.setAdapter(adapter);
return view;
}
protected void setData() {
strings.add("Hallo 5");
strings.add("Call of Duty 3");
strings.add("CS GO");
strings.add("FIFA 15");
strings.add("Assassin Creed 3");
strings.add("Angry Bird");
strings.add("Dark Soul");
}
}
BookFragment.java
package info.devexchanges.tabbarwithoutviewpager;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class BookFragment extends GameFragment {
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
return super.onCreateView(inflater, container, savedInstanceState);
}
protected void setData() {
strings.add("Gone with the wind");
strings.add("Kafka on the shore");
strings.add("Gone girl");
strings.add("Coffin dancer");
strings.add("Hannibal rising");
strings.add("A Study In Scarlet");
strings.add("Innocent in Death");
strings.add("Sense And Sensibility");
strings.add("Revenge Wears Prada");
}
}
ApplicationFragment.java
And their layout:
package info.devexchanges.tabbarwithoutviewpager;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class ApplicationFragment extends GameFragment {
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
return super.onCreateView(inflater, container, savedInstanceState);
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
protected void setData() {
strings.add("Job Search");
strings.add("Action Launcher 3");
strings.add("7 Minutes Workout");
strings.add("Hulu");
strings.add("Camera 360");
strings.add("Here");
strings.add("VLC");
strings.add("Khan Academy");
strings.add("Dasher Messenger");
strings.add("Next Lock Screen");
strings.add("Google Drive");
}
}
fragment_content.xml
After running, we have this output:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView
android:id="@+id/list_view"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
Final thoughts
ViewPager
using TabLayout
. Through this tip, I hope that you have learned more about Material Design in Android. Moreover, you can read this post to understanding how to disable swipe of ViewPager
and this post, to learned how to use ViewPagerIndicator library. Finally, downloading full code on @Github.