How to Create Custom Tab Layout with Animation in Android Studio
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
<TextView
android:layout_width="match_parent"
android:layout_height="55dp"
android:background="#4A6BFB"
android:gravity="center"
android:text="Custom Tabs"
android:textColor="#FFFFFF"
android:textSize="20sp"
android:textStyle="bold" />
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#4A6BFB">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="20dp"
android:background="@drawable/round_back_white10_100"
android:orientation="horizontal"
android:weightSum="3">
<TextView
android:id="@+id/tabItem1"
android:layout_width="0dp"
android:layout_height="50dp"
android:layout_weight="1"
android:background="@drawable/round_back_white_100"
android:gravity="center"
android:text="Tab Item 1"
android:textColor="#000000"
android:textStyle="bold" />
<TextView
android:id="@+id/tabItem2"
android:layout_width="0dp"
android:layout_height="50dp"
android:layout_weight="1"
android:gravity="center"
android:text="Tab Item 2"
android:textColor="#80FFFFFF" />
<TextView
android:id="@+id/tabItem3"
android:layout_width="0dp"
android:layout_height="50dp"
android:layout_weight="1"
android:gravity="center"
android:text="Tab Item 3"
android:textColor="#80FFFFFF" />
</LinearLayout>
</RelativeLayout>
<androidx.fragment.app.FragmentContainerView
android:id="@+id/fragmentContainer"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
MainActivity.java
package com.learnoset.customtabs;
import android.graphics.Color;
import android.graphics.Typeface;
import android.os.Bundle;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.TranslateAnimation;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
public class MainActivity extends AppCompatActivity {
private TextView tabItem1, tabItem2, tabItem3;
// selected tab number. we have 3 tabs so value must be lie between 1 - 3
// we are setting default value 1. because by default first tab will be selected
private int selectedTabNumber = 1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tabItem1 = findViewById(R.id.tabItem1);
tabItem2 = findViewById(R.id.tabItem2);
tabItem3 = findViewById(R.id.tabItem3);
// selecting first fragment by default
getSupportFragmentManager().beginTransaction()
.setReorderingAllowed(true)
.replace(R.id.fragmentContainer, FragmentOne.class, null)
.commit();
tabItem1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
selectTab(1);
}
});
tabItem2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
selectTab(2);
}
});
tabItem3.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
selectTab(3);
}
});
}
private void selectTab(int tabNumber) {
TextView selectedTextView;
TextView nonSelectedTextView1;
TextView nonSelectedTextView2;
// if you have more than three tabs then create nonSelectedTextView3.......n
if (tabNumber == 1) {
// user has selected first tab so 1st TextView is selected
selectedTextView = tabItem1;
// other two textviews are non selected
nonSelectedTextView1 = tabItem2;
nonSelectedTextView2 = tabItem3;
// setting fragment to the fragment container view
getSupportFragmentManager().beginTransaction()
.setReorderingAllowed(true)
.replace(R.id.fragmentContainer, FragmentOne.class, null)
.commit();
} else if (tabNumber == 2) {
// user has selected second tab so 2nd TextView is selected
selectedTextView = tabItem2;
// other two textviews are non selected. 1st and 3rd Tab is non selected
nonSelectedTextView1 = tabItem1;
nonSelectedTextView2 = tabItem3;
// setting fragment to the fragment container view
getSupportFragmentManager().beginTransaction()
.setReorderingAllowed(true)
.replace(R.id.fragmentContainer, FragmenTwo.class, null)
.commit();
} else {
// user has selected third tab so 3rd TextView is selected
selectedTextView = tabItem3;
// other two textviews are non selected. 1st and 2nd Tab is non selected
nonSelectedTextView1 = tabItem1;
nonSelectedTextView2 = tabItem2;
// setting fragment to the fragment container view
getSupportFragmentManager().beginTransaction()
.setReorderingAllowed(true)
.replace(R.id.fragmentContainer, FragmentThree.class, null)
.commit();
}
float slideTo = (tabNumber - selectedTabNumber) * selectedTextView.getWidth();
// creating translate animation
TranslateAnimation translateAnimation = new TranslateAnimation(0, slideTo, 0, 0);
translateAnimation.setDuration(100);
// checking for previously selected tab
if (selectedTabNumber == 1) {
tabItem1.startAnimation(translateAnimation);
} else if (selectedTabNumber == 2) {
tabItem2.startAnimation(translateAnimation);
} else {
tabItem3.startAnimation(translateAnimation);
}
translateAnimation.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
}
@Override
public void onAnimationEnd(Animation animation) {
// change design of selected tab's TextView
selectedTextView.setBackgroundResource(R.drawable.round_back_white_100);
selectedTextView.setTypeface(null, Typeface.BOLD);
selectedTextView.setTextColor(Color.BLACK);
// change design of non selected tab's TextViews
nonSelectedTextView1.setBackgroundColor(getResources().getColor(android.R.color.transparent));
nonSelectedTextView1.setTextColor(Color.parseColor("#80FFFFFF"));
nonSelectedTextView1.setTypeface(null, Typeface.NORMAL);
nonSelectedTextView2.setBackgroundColor(getResources().getColor(android.R.color.transparent));
nonSelectedTextView2.setTextColor(Color.parseColor("#80FFFFFF"));
nonSelectedTextView2.setTypeface(null, Typeface.NORMAL);
}
@Override
public void onAnimationRepeat(Animation animation) {
}
});
selectedTabNumber = tabNumber;
}
}
fragment_one.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".FragmentOne">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Fragment One"
android:textColor="#000000"
android:textSize="18sp"
android:layout_centerInParent="true"/>
</RelativeLayout>
</FrameLayout>
FragmentOne.java
package com.learnoset.customtabs;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.fragment.app.Fragment;
/**
* A simple {@link Fragment} subclass.
* Use the {@link FragmentOne#newInstance} factory method to
* create an instance of this fragment.
*/
public class FragmentOne 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;
public FragmentOne() {
// 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 FragmentOne.
*/
// TODO: Rename and change types and number of parameters
public static FragmentOne newInstance(String param1, String param2) {
FragmentOne fragment = new FragmentOne();
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_one, container, false);
}
}
fragment_fragmen_two.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".FragmenTwo">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Fragment Two"
android:textColor="#000000"
android:textSize="18sp"
android:layout_centerInParent="true"/>
</RelativeLayout>
</FrameLayout>
FragmentTwo.java
package com.learnoset.customtabs;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.fragment.app.Fragment;
/**
* A simple {@link Fragment} subclass.
* Use the {@link FragmenTwo#newInstance} factory method to
* create an instance of this fragment.
*/
public class FragmenTwo 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;
public FragmenTwo() {
// 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 FragmenTwo.
*/
// TODO: Rename and change types and number of parameters
public static FragmenTwo newInstance(String param1, String param2) {
FragmenTwo fragment = new FragmenTwo();
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_fragmen_two, container, false);
}
}
fragment_three.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".FragmentThree">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Fragment Three"
android:textColor="#000000"
android:textSize="18sp"
android:layout_centerInParent="true"/>
</RelativeLayout>
</FrameLayout>
FragmentThree.java
package com.learnoset.customtabs;
import android.os.Bundle;
import androidx.fragment.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
/**
* A simple {@link Fragment} subclass.
* Use the {@link FragmentThree#newInstance} factory method to
* create an instance of this fragment.
*/
public class FragmentThree 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;
public FragmentThree() {
// 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 FragmentThree.
*/
// TODO: Rename and change types and number of parameters
public static FragmentThree newInstance(String param1, String param2) {
FragmentThree fragment = new FragmentThree();
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_three, container, false);
}
}
round_back_white10_100.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="#1AFFFFFF"/>
<corners android:radius="100dp"/>
</shape>
round_back_white_100.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="100dp"/>
<solid android:color="#FFFFFF"/>
</shape>
Output
Projects with Source Code + Video Tutorials
You can download our Java and Android Studio Projects with Source Code and Video Tutorials.
Create your own Web Browser Source Code
Modern Login and Register screen UI design
Login and Register using Firebase Realtime Database
If you have any Questions or Queries
You can mail us at info.learnoset@gmail.com
Follow us to learn Coding and get in touch with new Technologies.