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.
Gamer Bazi - Tournament Application with Admob Ads & Web Admin Panel
Create your own Web Browser Source Code
Snake game android studio source code
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.