I-phone style tabbar in Android...

           By default we have a tabhost widget for android,that is shown at the top of the screen.This tabhost can be used effectively.But sometimes we want to move the tabhost at the bottom of the screen.There are to ways for this.
1:Using Relative Layout as a container of the tabhost childrens(i.e.:the tabcontents and the tab).
2:Give "android:layout_weight" the value "1".

1st approach(Using Relative Layout):
<?xml version="1.0" encoding="utf-8"?>
<TabHost xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@android:id/tabhost"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">
    <RelativeLayout
        android:layout_width="fill_parent"
        android:layout_height="fill_parent">
        <FrameLayout android:id="@android:id/tabcontent"
             android:layout_width="fill_parent"
             android:layout_height="fill_parent"
             android:layout_alignParentTop="true"
             android:layout_above="@android:id/tabs" />
    <TabWidget android:id="@android:id/tabs"
             android:layout_width="fill_parent"
             android:layout_height="wrap_content"
             android:layout_alignParentBottom="true" />
             //this property moves the tabwidget to bottom
    </RelativeLayout>
</TabHost>

Now the 2nd approach(Using "android:layout_weight"):
<?xml version="1.0" encoding="utf-8"?>
<TabHost xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@android:id/tabhost"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">
    <LinearLayout
        android:orientation="vertical"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:padding="5dp">
        <FrameLayout
            android:id="@android:id/tabcontent"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:padding="5dp"
            android:layout_weight="1"/>
            //this property moves the tabwidget to bottom
        <TabWidget
            android:id="@android:id/tabs"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_weight="0"/>
    </LinearLayout>
</TabHost>

But we want the I-phone style tab here.Now the tabhost is in bottom,but it does not look like the i-phone tabbar.
So we need to follow some steps that give us the following screen...
First of all make a new project with your desired name.Now define the "main.xml" in layout folder like this:
<?xml version="1.0" encoding="utf-8"?>
<TabHost xmlns:android="http://schemas.android.com/apk/res/android"
 android:id="@android:id/tabhost" android:layout_width="fill_parent"
 android:layout_height="fill_parent">
 <LinearLayout android:orientation="vertical"
  android:layout_width="fill_parent" android:layout_height="fill_parent">
  <FrameLayout android:id="@android:id/tabcontent"
   android:layout_width="fill_parent" android:layout_height="0dip"
   android:layout_weight="1" /> 
  <TabWidget android:id="@android:id/tabs"
   android:layout_width="fill_parent" android:layout_height="wrap_content"
   android:layout_weight="0"  />
 </LinearLayout>
</TabHost>



Now we will design the tabbar look in "tab_indicator.xml" in layout folder.Here we take a imageview and a textview.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="0dip"
    android:layout_height="55dip"    
    android:layout_weight="1"
    android:orientation="vertical"
    
    android:background="@drawable/tab_indicator"
    android:padding="5dp">

    <ImageView android:id="@+id/icon"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:src="@drawable/icon"      
    /> 
    <TextView android:id="@+id/title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true" 
        android:layout_centerHorizontal="true"
        style="?android:attr/tabWidgetStyle"
    />    
</RelativeLayout>

Now to render the xml properly,we need to define some  png files and xml files in the drawable folder.These are:
png file names: home_normal.png ,home_selected.png,search_normal.png ,search_selected.png.You can use your own pngs with this names.(You can also use your own desired names.In that case change in the code accordingly.)
"tab_indicator.xml"(These time in the drawable folder):
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
 <!-- Non focused states -->
 <item android:state_focused="false" android:state_selected="false"
  android:state_pressed="false" android:drawable="@drawable/tab_unselected" />
 <item android:state_focused="false" android:state_selected="true"
  android:state_pressed="false" android:drawable="@drawable/tab_selected" />

 <!-- Focused states -->
 <item android:state_focused="true" android:state_selected="false"
  android:state_pressed="false" android:drawable="@drawable/tab_focus" />
 <item android:state_focused="true" android:state_selected="true"
  android:state_pressed="false" android:drawable="@drawable/tab_focus" />

 <!-- Pressed -->
 <item android:state_selected="true" android:state_pressed="true"
  android:drawable="@drawable/tab_focus" />
 <item android:state_pressed="true" android:drawable="@drawable/tab_press" />
</selector>

tab_selected.xml:

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
 <!-- draw tab background -->
 <item android:left="@dimen/tab_space" android:right="@dimen/tab_space">
  <shape android:shape="rectangle">

   <gradient android:angle="-90" android:startColor="@color/tabMedium"
    android:endColor="@color/tabDark" />
  </shape>
 </item>

 <item android:top="1sp" android:bottom="26sp" >
  <shape android:shape="rectangle">
   <solid android:color="@color/tabTransparent" />
  </shape>
 </item>
 <item android:left="2sp" android:top="3sp" android:right="2sp"
  android:bottom="2sp">
  <shape android:shape="rectangle">
   <corners android:bottomLeftRadius="@dimen/corner_radius"
    android:bottomRightRadius="@dimen/corner_radius"
    android:topLeftRadius="@dimen/corner_radius" android:topRightRadius="@dimen/corner_radius" />
   <gradient android:angle="-90" android:startColor="#20ffffff"
    android:endColor="#20ffffff" />
  </shape>
 </item>
</layer-list>

tab_unselected.xml:

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
 
 <item android:left="@dimen/tab_space" android:right="@dimen/tab_space"> 
  <shape android:shape="rectangle">
   
   <gradient android:angle="-90" android:startColor="@color/tabMedium"
    android:endColor="@color/tabDark" />
   
  </shape>
 </item>
 <item android:top="1sp" android:bottom="26sp" > 
  <shape android:shape="rectangle">
   <solid android:color="@color/tabTransparent"/>
 </shape>
  
 </item>
</layer-list>

tab_search.xml:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
 <item android:drawable="@drawable/search_selected"
  android:state_selected="true" />
 <item android:drawable="@drawable/search_normal" />
</selector>

tab_press.xml:

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
 <item android:left="@dimen/tab_space" android:right="@dimen/tab_space"> 
  <shape android:shape="rectangle">
   <gradient android:angle="-90" android:startColor="@color/tabMedium"
    android:endColor="@color/tabDark" />
  
  </shape>
 </item>
 <!-- draw tab background -->
 <item android:top="1sp" android:bottom="26sp">
  <shape android:shape="rectangle">
   <solid android:color="@color/tabTransparent" />
  </shape>
 </item>
 <item android:left="2sp" android:top="3sp"
                android:right="2sp" android:bottom="2sp"> 
  <shape android:shape="rectangle">
   <corners android:bottomLeftRadius="@dimen/corner_radius"
    android:bottomRightRadius="@dimen/corner_radius" 
    android:topLeftRadius="@dimen/corner_radius"
    android:topRightRadius="@dimen/corner_radius"
    />
   <gradient android:angle="-90" android:startColor="#20ffffff"
   
    android:endColor="#20ffffff" />
   
  </shape>
 </item>
</layer-list>

tab_home.xml:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
 <item android:drawable="@drawable/home_selected"
  android:state_selected="true" />
 <item android:drawable="@drawable/home_normal" />
</selector>

tab_focus.xml:

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
 <item android:left="@dimen/tab_space" android:right="@dimen/tab_space"> 
  <shape android:shape="rectangle">
   
   <gradient android:angle="-90" android:startColor="@color/tabMedium"
    android:endColor="@color/tabDark" />     
  </shape>
 </item>
 <!-- draw tab background -->
 <item android:top="1sp" android:bottom="26sp" >
  <shape android:shape="rectangle">
   <solid android:color="@color/tabTransparent" /> 
  </shape>
 </item>
 
 <item android:left="2sp" android:top="3sp"
       android:right="2sp" android:bottom="2sp" > 
  <shape android:shape="rectangle">
   <corners android:bottomLeftRadius="@dimen/corner_radius"
    android:bottomRightRadius="@dimen/corner_radius" 
    android:topLeftRadius="@dimen/corner_radius"
    android:topRightRadius="@dimen/corner_radius"
    />
   <gradient android:angle="-90" android:startColor="#20ffffff"
    android:endColor="#20ffffff" />
   
  </shape>
 </item>
</layer-list>

app_background.xml:

<?xml version="1.0" encoding="utf-8"?>
<shape android:shape="rectangle" xmlns:android="http://schemas.android.com/apk/res/android">
 <solid android:color="#ffffff" />
</shape>

Now define the java files.Here the main activity class is TabSample.java.

package app.tabsample;

import android.app.TabActivity;
import android.content.Intent;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ImageView;
import android.widget.TabHost;
import android.widget.TextView;


/**
 * @author www.androidcookers.co.cc
 * {@link www.androidcookers.co.cc}
 *
 */
public class TabSample extends TabActivity {
 /** Called when the activity is first created. */ 
 public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.main);
  setTabs() ;
 }
 private void setTabs()
 {
  addTab("Home", R.drawable.tab_home, ArrowsActivity.class);
  addTab("Search", R.drawable.tab_search, OptionsActivity.class);

  //To add more tabs just use addTab() method here like previous line.
 }
 
 private void addTab(String labelId, int drawableId, Class c)
 {
  TabHost tabHost = getTabHost();
  Intent intent = new Intent(this, c);
  TabHost.TabSpec spec = tabHost.newTabSpec("tab" + labelId); 
  
  View tabIndicator =LayoutInflater.from(this).inflate(R.layout.tab_indicator, getTabWidget(), false);
  TextView title = (TextView) tabIndicator.findViewById(R.id.title);
  title.setText(labelId);
  ImageView icon = (ImageView) tabIndicator.findViewById(R.id.icon);
  icon.setImageResource(drawableId);
  
  spec.setIndicator(tabIndicator);
  spec.setContent(intent);
  tabHost.addTab(spec);
 }
}

Here we call two classes named "ArrowsActivity" and "OptionsActivity".Lets define it:
"ArrowsActivity.java"
package app.tabsample;

import android.app.Activity;
import android.os.Bundle;

/**
 * @author www.androidcookers.co.cc
 * {@link www.androidcookers.co.cc}
 *
 */
public class ArrowsActivity extends Activity {
 
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.arrowspage);      
    }
}

And the associated xml:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
 android:layout_height="fill_parent" android:layout_width="fill_parent">
 <TextView android:layout_height="wrap_content"
  android:layout_width="wrap_content" android:text="Welcome"
  android:layout_centerInParent="true" android:textSize="20sp"/>
</RelativeLayout>

Now the "OptionsActivity.class"

package app.tabsample;

import android.app.Activity;
import android.os.Bundle;

/**
 * @author www.androidcookers.co.cc
 * {@link www.androidcookers.co.cc}
 *
 */
public class OptionsActivity extends Activity {
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.tab2);               
    }
}

And the associated xml:

<?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"
    android:orientation="vertical" android:background="#ffffff">

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hey,go to www.androidcookers.co.cc to enjoy more about android" android:textSize="30sp" android:textColor="#520000"/>

</LinearLayout>

Now your project is complete.Run it to see the result.
You can download the full source code from here.

7 comments:

  1. How about scrolling in tabs area ?

    ReplyDelete
  2. Hey this is really great! Any chance you can show how to set an OnTabChanged or onClickListener to this? I am having difficulty relaunching/refreshing my activities when I switch tabs and keeping the tabs remaining visible.

    ReplyDelete
  3. wonderful tutorial..:).The footer appears smaller on high resolutions 1280x720.Any way to increase it?

    ReplyDelete