So, first we need to create a really simple layout for each Tab.
layout/custom_tab.xml
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/tabTitleText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:clickable="true"
android:padding="5dp"
android:textSize="15sp"
android:textStyle="bold"
android:ellipsize="marquee"
android:singleLine="true"
android:textColor="@color/tab_textcolor"
android:background="@drawable/tab_selector"/>
That's it for my Tab view! Clickable set to true because i want to color to change to white when pressing the tab. Padding of course, otherwise it'll be to small and singleline so it won't wrap around. Next our text color selector.
color/tab_textcolor.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_selected="true" android:color="#FFFFFF" />
<item android:state_pressed="true" android:color="#FFFFFF" />
<item android:color="@android:color/darker_gray" />
</selector>
Nothing special here, text color will be white when tab is selected or pressed, otherwise gray.
drawable/tab_selector.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_selected="true" android:state_pressed="false"
android:drawable="@drawable/tab_bg_selected" />
<item android:state_selected="false" android:state_pressed="false"
android:drawable="@drawable/tab_bg_unselected" />
<item android:state_pressed="true"
android:drawable="@drawable/tab_bg_pressed" />
</selector>
Three different backgrounds for our TextView, selected, unselected and pressed.
drawable/tab_bg_selected.xml
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item >
<shape android:shape="rectangle">
<solid android:color="#FFFFFF" />
<corners android:topLeftRadius="5dp" android:topRightRadius="5dp"/>
</shape>
</item>
<item android:top="1dp" android:bottom="2dp" android:left="1dp" android:right="1dp">
<shape android:shape="rectangle">
<gradient
android:startColor="#ff1673"
android:endColor="#e6acc3"
android:angle="270"
android:type="linear"
/>
<corners android:topLeftRadius="5dp" android:topRightRadius="5dp"/>
</shape>
</item>
</layer-list>
Link to <layer-list> at Google. First we create a white colored rectangle (just gonna use it as a border), then we create our gradient on top of it but set the offset so we'll get white borders. Can use <stroke> but then we cant control the border, i wanted different widths and sometimes no width. Like when it's unselected.
drawable/tab_bg_unselected.xml
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:top="10dp">
<shape android:shape="rectangle">
<solid android:color="#FFFFFF" />
</shape>
</item>
<item android:bottom="2dp">
<shape android:shape="rectangle">
<gradient android:centerColor="#655e5e" android:startColor="#3e3e3e"
android:endColor="#807c7c"
android:angle="-90" />
<corners android:topLeftRadius="4dp" android:topRightRadius="4dp"/>
</shape>
</item>
</layer-list>
Our unselected tab background. First a white rectangle, i want a border at the bottom. Notice i placed android:top="10dp" , need to offset it so it wont be white at the top corners in the gradient.
drawable/tab_bg_pressed.xml
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item >
<shape android:shape="rectangle">
<solid android:color="#FFFFFF" />
<corners android:topLeftRadius="5dp" android:topRightRadius="5dp"/>
</shape>
</item>
<item android:top="1dp" android:bottom="2dp" android:left="1dp" android:right="1dp">
<shape android:shape="rectangle">
<solid android:color="#ff1673" />
<corners android:topLeftRadius="5dp" android:topRightRadius="5dp"/>
</shape>
</item>
</layer-list>
Looks like the first one except i just use a solid color when it's pressed. Sneak peek of the layout :
Lets move along to the startup screen layout.
layout/main.xml
<?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"
android:layout_marginTop="2dp">
<LinearLayout
android:paddingTop="2dp"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TabWidget
android:id="@android:id/tabs"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
<FrameLayout
android:id="@android:id/tabcontent"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
/>
</LinearLayout>
</TabHost>
Standard TabHost, taken from the Android Developers homepage. Tab Layout Example.
layout/view_testlayout.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_marginTop="5dp">
<Button android:id="@+id/button_Test"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
</LinearLayout>
The layout for the activites we create in the tabs.
src/MyActivity.java
import android.app.TabActivity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.TabHost;
import android.widget.TextView;
public class MyActivity extends TabActivity
{
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
TabHost tabHost = getTabHost(); // The activity TabHost
TabHost.TabSpec spec; // Resusable TabSpec for each tab
Intent intent; // Reusable Intent for each tab
// Create an Intent to launch an Activity for the tab (to be reused)
intent = new Intent().setClass(this, TestActivity.class);
// Create our custom view.
View tabView = createTabView(this, "Tab 1");
// Initialize a TabSpec for each tab and add it to the TabHost
spec = tabHost.newTabSpec("tab1").setIndicator(tabView)
.setContent(intent);
tabHost.addTab(spec);
// Do the same for the other tabs
tabView = createTabView(this, "Tab 2");
intent = new Intent().setClass(this, TestActivity.class);
spec = tabHost.newTabSpec("tab2").setIndicator(tabView)
.setContent(intent);
tabHost.addTab(spec);
}
private static View createTabView(Context context, String tabText) {
View view = LayoutInflater.from(context).inflate(R.layout.tab_custom, null, false);
TextView tv = (TextView) view.findViewById(R.id.tabTitleText);
tv.setText(tabText);
return view;
}
}
src/TestActivity.java
import android.app.Activity;
import android.os.Bundle;
import android.widget.Button;
public class TestActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.view_testlayout);
MyActivity myActivity = (MyActivity) this.getParent();
String currentTab = myActivity.getTabHost().getCurrentTabTag();
((Button)findViewById(R.id.button_Test)).setText(currentTab);
}
}
Nothing strange here, i really like the drawables through XML, works fine for basic layout! So many different .PNG's to keep track of when customizing a Tab layout. Final screenshot :
I have a small problem though, did you notice ? I did smaller corners in the unselected tab. The tab_bg_selected drawable still seems to be there even though it's not selected. If i do a larger corner radius, like 10dp it will look like this.
Update!
Didnt really found a solution why the selected drawable still is drawn when unselected so i just updated the tab_bg_unselected.xml layer-list with a rectangle that's the same color as the background.
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="rectangle">
<solid android:color="@color/background_color" />
</shape>
</item>
<item android:top="20dp">
<shape android:shape="rectangle">
<solid android:color="#FFFFFF" />
</shape>
</item>
<item android:bottom="2dp">
<shape android:shape="rectangle">
<gradient android:centerColor="#655e5e" android:startColor="#3e3e3e"
android:endColor="#807c7c"
android:angle="-90" />
<corners android:topLeftRadius="10dp" android:topRightRadius="10dp"/>
</shape>
</item>
</layer-list>
No more visible corners ! : )