Kotlin Change Tab Icon/Text/Background Color/Text Color When Selected

kotlin sqlite multiple tables, kotlin recyclerview checkbox, kotlin recyclerview button, kotlin load html javascript, kotlin recyclerview searchview, kotlin recyclerview search using edittext, kotlin listview with edittext, kotlin recyclerview with edittext, kotlin swipe to delete listview, kotlin recyclerview swipe to delete, kotlin expandablelistview with checkbox, kotlin custom ratingbar, kotlin change tab, Kotlin Select Multiple Images From Gallery, Kotlin Custom Dialog With Image And Title, kotlin select multiple video

This topic is on Kotlin Change Tab Icon/Text/Background Color/Text Color.

We will change the icon , color ,text color, background color etc. of the android tab when it is selected by the user.

This feature is mainly used for indicating the current selected tab. Developers change the text and icon color of selected tab so that it can be differentiated from other deselected tabs easily.

First of all, watch the below youtube content.

 

Step 1. Adding Colors

Go to app->res->values directory and open the colors.xml file. Add the following lines in it

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="colorPrimary">#525e5e</color>
    <color name="colorPrimaryDark">#41f8f8</color>
    <color name="colorAccent">#525e5e</color>
    <color name="greyback">#1e2926</color>
    <color name="black">#000000</color>
    <color name="view">#5e6664</color>
    <color name="tranparent">#00ffffff</color>
    <color name="white">#FFFFFF</color>
</resources>

Step 2. Some Strings

Now in the same directory of app->res->values open a file called strings.xml

strings.xml file should have the below code lines

<resources>
    <string name="app_name">ChangeTabKotlin</string>

    <string name="login">Login</string>
    <string name="intro">Introduction</string>
    <string name="Product">Product</string>
    <string name="Location">Location</string>

    <!-- TODO: Remove or change this placeholder text -->
    <string name="hello_blank_fragment">Hello blank fragment</string>
</resources>

Step 3. Some Icons

We want to change the icon of the selected tab. For this, we need to add different icons for both the states of the tab : selected and deselected

And these two types of icons are different for different tabs.

Click on the following to download various icons.

Hit me to download icons.

Now you need to copy all these icon images into the app->res->mipmap folder.

Step 4. Necessary Fragments

We will create fragment for each tab. This example has four tabs so we will have to create four new fragments.

So go on and make a new fragment called IntroFragment

In your fragment_intro.xml file, add the following

<?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=".IntroFragment">

    <!-- TODO: Update blank fragment layout -->
    <TextView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center"
        android:textSize="50sp"
        android:text="@string/intro" />

</FrameLayout>

Below is the code for IntroFragment.kt file.

import android.os.Bundle
import android.support.v4.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup

class IntroFragment : Fragment() {

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_intro, container, false)
    }

}

Second fragment is LocationFragment

Code for fragment_location.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=".LocationFragment">

    <!-- TODO: Update blank fragment layout -->
    <TextView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center"
        android:textSize="50sp"
        android:text="Location" />

</FrameLayout>

Following is for LocationFragment.kt

import android.os.Bundle
import android.support.v4.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup

class LocationFragment : Fragment() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

    }

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_location, container, false)
    }

}

Then next fragment is Login Fragment

Following is as fragment_login.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=".LoginFragment">

    <!-- TODO: Update blank fragment layout -->
    <TextView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center"
        android:textSize="50sp"
        android:text="@string/login" />

</FrameLayout>

And about LoginFragment.kt

import android.os.Bundle
import android.support.v4.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup

class LoginFragment : Fragment() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

    }

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_login, container, false)
    }

}

Next one is Product fragment which is the last.

Below is code for fragment_product.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=".ProductFragment">

    <!-- TODO: Update blank fragment layout -->
    <TextView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center"
        android:textSize="50sp"
        android:text="@string/Product" />

</FrameLayout>

Copy the following into ProductFragment.kt

import android.os.Bundle
import android.support.v4.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup

class ProductFragment : Fragment() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

    }

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_product, container, false)
    }

}

Step 5. Last in on Main Files

Now we are left with main files only.

Write down the below source lines in activity_main.xml file.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

    <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="50dp"
            android:orientation="horizontal"
            android:background="@mipmap/tab_bar_bg"
            android:layout_marginTop="5dp"
            android:layout_marginBottom="5dp"
            android:layout_marginRight="5dp"
            android:layout_marginLeft="5dp">


        <LinearLayout
                android:orientation="vertical"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:id="@+id/llIntro">

            <ImageView
                    android:layout_width="match_parent"
                    android:layout_height="0dp"
                    android:layout_weight="1"
                    android:layout_marginTop="5dp"
                    android:paddingTop="5dp"
                    android:id="@+id/ivIntro"
                    android:src="@mipmap/icon_intro_normal"
                    android:foregroundGravity="center"
            />

            <TextView
                    android:layout_width="match_parent"
                    android:layout_height="0dp"
                    android:text="@string/intro"
                    android:id="@+id/tvIntro"
                    android:layout_weight="1"
                    android:textSize="12sp"
                    android:gravity="center" />

        </LinearLayout>

        <View
                android:layout_width="0.5dp"
                android:layout_height="match_parent"
                android:background="@color/view"
        />

        <LinearLayout
                android:orientation="vertical"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:id="@+id/llProduct"
        >

            <ImageView
                    android:layout_width="match_parent"
                    android:layout_height="0dp"
                    android:layout_weight="1"
                    android:layout_marginTop="5dp"
                    android:paddingTop="5dp"
                    android:foregroundGravity="center"
                    android:id="@+id/ivProduct"
                    android:src="@mipmap/icon_product"
            />

            <TextView
                    android:layout_width="match_parent"
                    android:layout_height="0dp"
                    android:text="@string/Product"
                    android:id="@+id/tvProduct"
                    android:layout_weight="1"
                    android:gravity="center"
                    android:textSize="12sp" />
        </LinearLayout>

        <View
                android:layout_width="0.5dp"
                android:layout_height="match_parent"
                android:background="@color/view"
        />

        <LinearLayout
                android:orientation="vertical"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:id="@+id/llLocation"
        >
            <ImageView
                    android:layout_width="match_parent"
                    android:layout_height="0dp"
                    android:layout_weight="1"
                    android:layout_marginTop="5dp"
                    android:paddingTop="5dp"
                    android:id="@+id/ivLocation"
                    android:src="@mipmap/icon_location"
            />

            <TextView
                    android:layout_width="match_parent"
                    android:layout_height="0dp"
                    android:text="@string/Location"
                    android:id="@+id/tvLocation"
                    android:layout_weight="1"
                    android:gravity="center"
                    android:textSize="12sp" />
        </LinearLayout>

        <View
                android:layout_width="0.5dp"
                android:layout_height="match_parent"
                android:background="@color/view"
        />

        <LinearLayout
                android:orientation="vertical"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:id="@+id/llLogin"
        >
            <ImageView
                    android:layout_width="match_parent"
                    android:layout_height="0dp"
                    android:layout_weight="1"
                    android:layout_marginTop="5dp"
                    android:paddingTop="5dp"
                    android:id="@+id/ivLogin"
                    android:src="@mipmap/icon_login2"
            />

            <TextView
                    android:layout_width="match_parent"
                    android:layout_height="0dp"
                    android:text="@string/login"
                    android:id="@+id/tvLogin"
                    android:layout_weight="1"
                    android:gravity="center"
                    android:textSize="12sp" />
        </LinearLayout>
    </LinearLayout>

    <FrameLayout
            android:id="@+id/container_body"
            android:layout_width="match_parent"
            android:layout_height="match_parent">

    </FrameLayout>

</LinearLayout>

This file is creating the layout of our tabs. We will set all the icons on this file.

By default, we will set the icons for deselected files. Logic for presenting and changing icons will be written in the Main Kotlin file.

Now write the below source code lines in MainActivity.kt file.

import android.support.v4.app.Fragment
import android.support.v4.app.FragmentManager
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.TextView

class MainActivity : AppCompatActivity() {

    private var currentSelected = 0
    private val intro = "intro"
    private val product = "product"
    private val location = "location"
    private val login = "login"

    private var ivIntro: ImageView? = null
    private var ivProduct: ImageView? = null
    private var ivLocation: ImageView? = null
    private var ivLogin: ImageView? = null
    private var tvIntro: TextView? = null
    private var tvProduct: TextView? = null
    private var tvLocation: TextView? = null
    private var tvLogin: TextView? = null
    private var llIntro: LinearLayout? = null
    private var llProduct: LinearLayout? = null
    private var llLocation: LinearLayout? = null
    private var llLogin: LinearLayout? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        llIntro = findViewById(R.id.llIntro) as LinearLayout
        llProduct = findViewById(R.id.llProduct) as LinearLayout
        llLocation = findViewById(R.id.llLocation) as LinearLayout
        llLogin = findViewById(R.id.llLogin) as LinearLayout

        ivIntro = findViewById(R.id.ivIntro) as ImageView
        ivProduct = findViewById(R.id.ivProduct) as ImageView
        ivLocation = findViewById(R.id.ivLocation) as ImageView
        ivLogin = findViewById(R.id.ivLogin) as ImageView

        tvIntro = findViewById(R.id.tvIntro) as TextView
        tvProduct = findViewById(R.id.tvProduct) as TextView
        tvLocation = findViewById(R.id.tvLocation) as TextView
        tvLogin = findViewById(R.id.tvLogin) as TextView

        llIntro!!.setOnClickListener {
            if (currentSelected == 1) {

            } else {
                supportActionBar!!.title = "Introduction"
                ivIntro!!.setImageResource(R.mipmap.icon_intro_selected)
                tvIntro!!.setTextColor(resources.getColor(R.color.white))
                llIntro!!.setBackgroundDrawable(resources.getDrawable(R.drawable.roundleft))
                unselectElse(1)
                removeAllFragment(IntroFragment(), false, intro)
            }
        }

        llProduct!!.setOnClickListener {
            if (currentSelected == 2) {

            } else {
                supportActionBar!!.title = "Product"
                ivProduct!!.setImageResource(R.mipmap.icon_product_selected)
                tvProduct!!.setTextColor(resources.getColor(R.color.white))
                llProduct!!.setBackgroundColor(resources.getColor(R.color.colorPrimary))
                unselectElse(2)
                removeAllFragment(ProductFragment(), false, product)
            }
        }

        llLocation!!.setOnClickListener {
            if (currentSelected == 3) {

            } else {
                supportActionBar!!.title = "Location"
                ivLocation!!.setImageResource(R.mipmap.icon_location_selected)
                tvLocation!!.setTextColor(resources.getColor(R.color.white))
                llLocation!!.setBackgroundColor(resources.getColor(R.color.colorPrimary))
                unselectElse(3)
                removeAllFragment(LocationFragment(), false, location)
            }
        }

        llLogin!!.setOnClickListener {
            if (currentSelected == 4) {

            } else {
                supportActionBar!!.title = "Login"
                ivLogin!!.setImageResource(R.mipmap.icon_login_selected)
                tvLogin!!.setTextColor(resources.getColor(R.color.white))
                llLogin!!.setBackgroundDrawable(resources.getDrawable(R.drawable.roundback))
                unselectElse(4)
                removeAllFragment(LoginFragment(), false, login)
            }
        }

    }

    private fun unselectElse(current: Int) {
        when (currentSelected) {
            1 -> {
                ivIntro!!.setImageResource(R.mipmap.icon_intro_normal)
                tvIntro!!.setTextColor(resources.getColor(R.color.colorPrimary))
                llIntro!!.setBackgroundColor(resources.getColor(R.color.tranparent))
                currentSelected = current
            }
            2 -> {
                ivProduct!!.setImageResource(R.mipmap.icon_product)
                tvProduct!!.setTextColor(resources.getColor(R.color.colorPrimary))
                llProduct!!.setBackgroundColor(resources.getColor(R.color.tranparent))
                currentSelected = current
            }
            3 -> {
                ivLocation!!.setImageResource(R.mipmap.icon_location)
                tvLocation!!.setTextColor(resources.getColor(R.color.colorPrimary))
                llLocation!!.setBackgroundColor(resources.getColor(R.color.tranparent))
                currentSelected = current
            }
            4 -> {
                ivLogin!!.setImageResource(R.mipmap.icon_login2)
                tvLogin!!.setTextColor(resources.getColor(R.color.colorPrimary))
                llLogin!!.setBackgroundColor(resources.getColor(R.color.tranparent))
                currentSelected = current
            }
        }
        if (currentSelected == 0) {
            currentSelected = current
        }
    }

    fun removeAllFragment(replaceFragment: Fragment, addToBackStack: Boolean, tag: String) {

        val manager = supportFragmentManager
        val ft = manager.beginTransaction()
        manager.popBackStackImmediate(null, FragmentManager.POP_BACK_STACK_INCLUSIVE)

        if (addToBackStack) {
            ft.addToBackStack(tag)
        }
        ft.replace(R.id.container_body, replaceFragment)
        ft.commitAllowingStateLoss()
    }

}

Deep Information

Compiler will first define some image views, text views and linear layouts.

Linear layout represent the background of whole one tab. We have four different linear layouts for four various tabs.

First of all, see the following

   llIntro!!.setOnClickListener {
            if (currentSelected == 1) {

            } else {
                supportActionBar!!.title = "Introduction"
                ivIntro!!.setImageResource(R.mipmap.icon_intro_selected)
                tvIntro!!.setTextColor(resources.getColor(R.color.white))
                llIntro!!.setBackgroundDrawable(resources.getDrawable(R.drawable.roundleft))
                unselectElse(1)
                removeAllFragment(IntroFragment(), false, intro)
            }
        }

When the user clicks the intro tab, compiler will run the above code.

It will first check, if the value of the variable currentSelected is 1 or not. If it is 1 then it means that Intro tag is already selected and we do not need to do anything.

If it is not 1 then compiler will go into the else statement. Here, compiler will change the value of the supportActionBar.

Then it will change the image of the tab using setImageResource() method.

After this, it will use setTextColor() method to change the color of the tab text.

Then compiler will change the background of the tab using setBackgroundDrawable() method.

Below is the code for unselectElse() method.

 private fun unselectElse(current: Int) {
        when (currentSelected) {
            1 -> {
                ivIntro!!.setImageResource(R.mipmap.icon_intro_normal)
                tvIntro!!.setTextColor(resources.getColor(R.color.colorPrimary))
                llIntro!!.setBackgroundColor(resources.getColor(R.color.tranparent))
                currentSelected = current
            }
            2 -> {
                ivProduct!!.setImageResource(R.mipmap.icon_product)
                tvProduct!!.setTextColor(resources.getColor(R.color.colorPrimary))
                llProduct!!.setBackgroundColor(resources.getColor(R.color.tranparent))
                currentSelected = current
            }
            3 -> {
                ivLocation!!.setImageResource(R.mipmap.icon_location)
                tvLocation!!.setTextColor(resources.getColor(R.color.colorPrimary))
                llLocation!!.setBackgroundColor(resources.getColor(R.color.tranparent))
                currentSelected = current
            }
            4 -> {
                ivLogin!!.setImageResource(R.mipmap.icon_login2)
                tvLogin!!.setTextColor(resources.getColor(R.color.colorPrimary))
                llLogin!!.setBackgroundColor(resources.getColor(R.color.tranparent))
                currentSelected = current
            }
        }
        if (currentSelected == 0) {
            currentSelected = current
        }
    }

This method will get the number of current selected tab. Here, it will use when() method. This method have four different conditions.

When first tab (introduction) is selected, value for when() method will be 1.

Thus, compiler will execute the lines associated with option 1 in the when() method.

Following are the code lines for removeAllFragment() method.

  fun removeAllFragment(replaceFragment: Fragment, addToBackStack: Boolean, tag: String) {

        val manager = supportFragmentManager
        val ft = manager.beginTransaction()
        manager.popBackStackImmediate(null, FragmentManager.POP_BACK_STACK_INCLUSIVE)

        if (addToBackStack) {
            ft.addToBackStack(tag)
        }
        ft.replace(R.id.container_body, replaceFragment)
        ft.commitAllowingStateLoss()
    }

This method will first remove all the current opened fragments. Then it will simply open the new fragment which user have selected. For example, if user have selected last tab (login) then this method will first empty the fragment back stack and then it will open the Login Fragment in container_body

Download For Kotlin Change Tab

https://github.com/demonuts/Kotlin-Change-Tab-Icon-Text-Background-Color-Text-Color-When-Selected