对于2.3系统来说tabhost还是比较常用的一种viewGroup,但是android SDK自带的都是在上面切换显示的tabhost,我的文章呢,是将其定义在底下。
上个图,不上图没有说服力。
图已经有了,接下来就是讲一下如何实现,也是最关键的。
1、自定义TabhostActivity类
package com.smartUI;
import android.app.TabActivity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.TabHost;
import android.widget.TabHost.TabSpec;
import android.widget.TabWidget;
import android.widget.TextView;
import com.smarthome1.R;
public abstract class TabHostActivity extends TabActivity {
private static final String TAG = "TabActivity";
private TabHost mTabHost;
private TabWidget mTabWidget;
private LayoutInflater mLayoutflater;//寻找layout的下的XML,并将之转化为VIEW
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// set theme because we do not want the shadow
setContentView(R.layout.ui_tabhost);
Log.i(TAG, "------------------this is TabActivity-----------");
mLayoutflater = getLayoutInflater();
mTabHost = getTabHost(); //Returns the TabHost the activity is using to host its tabs
mTabWidget = getTabWidget();//Returns the TabWidget the activity is using to draw the actual tabs.
prepare();
initTabSpec();
}
private void initTabSpec() {
Log.i(TAG, "initTabSpec");
int count = getTabItemCount(); //获取当前tabItem的数目
for (int i = 0; i < count; i++) {
// set text view
View tabItem = mLayoutflater.inflate(R.layout.ui_tabhost_item, null);//转换当前view
TextView tvTabItem = (TextView) tabItem.findViewById(R.id.tab_itme_txt);
setTabItemTextView(tvTabItem, i);
// set id
String tabItemId = getTabItemId(i);
// set tab spec
TabSpec tabSpec = mTabHost.newTabSpec(tabItemId);
tabSpec.setIndicator(tabItem);
tabSpec.setContent(getTabItemIntent(i));
mTabHost.addTab(tabSpec);
}
}
/*****************************************************
* 再调用时,重写函数
* */
protected void prepare() {
// do nothing or you override it
}
/*****************************************************
* 再调用时,重写函数
* */
protected View getTop() {
// do nothing or you override it
return null;
}
protected int getTabCount() {
return mTabHost.getTabWidget().getTabCount();
}
/** TabItem函数功能*****************************************/
abstract protected void setTabItemTextView(TextView textView, int position);
abstract protected String getTabItemId(int position);
abstract protected Intent getTabItemIntent(int position);
abstract protected int getTabItemCount();
protected void setCurrentTab(int index) {
mTabHost.setCurrentTab(index);
}
protected void focusCurrentTab(int index) {
mTabWidget.focusCurrentTab(index);
}
}
这里我一步步讲解框架的构成机理,TabhostActivity继承了Tabhost。当然我们需要与框架配合的XML文件,这里我截个图,做一下简单的说明,讲完XML在回来讲解
TabhostActivity类,XML也算在小标题1里面。
XML文件:
ui_tabhost.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" >
<RelativeLayout
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"
android:layout_above="@android:id/tabs" >
</FrameLayout>
<TabWidget
android:id="@android:id/tabs"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:background="@drawable/channelgallery_bg" >
</TabWidget>
</RelativeLayout>
</TabHost>
ui_tabhost_item.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:gravity="center"
android:orientation="vertical" >
<TextView
android:id="@+id/tab_itme_txt"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="TextView" />
</LinearLayout>
xml中的部分图片可能没有,可在http://download.csdn.net/detail/feiyangxiaomi/5507339 自行下载源码。
继续回到我们刚才的话题,TabhostActivity类这里主要是prepare();准备设置 initTabSpec();初始化底部菜单。当然有人会问,问什么定义那么多没有内容的的函数,或者说为什么有的函数只做了声明,这个下节我会专门写一下。
2 定义自己的每一个标签类型,每一种标签显示方式一般都是不同的,有的一个图标配合文字,有的只是文字。
package com.smartUI;
import android.content.Intent;
public class TabItem {
private String title; // tab item title
private int icon; // tab item icon
private int bg; // tab item background
private Intent intent; // tab item intent
public TabItem(String title, int icon, int bg, Intent intent) {
super();
this.title = title;
this.icon = icon;
this.bg = bg;
this.intent = intent;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public int getIcon() {
return icon;
}
public void setIcon(int icon) {
this.icon = icon;
}
public int getBg() {
return bg;
}
public void setBg(int bg) {
this.bg = bg;
}
public Intent getIntent() {
return intent;
}
public void setIntent(Intent intent) {
this.intent = intent;
}
}
3 实现底部显示功能
package com.smarthome1;
import java.util.ArrayList;
import java.util.List;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.widget.TabWidget;
import android.widget.TextView;
import com.smartUI.Tab1Activity;
import com.smartUI.TabHostActivity;
import com.smartUI.TabItem;
/***********************************************************************
*
*
* */
public class MainActivity extends TabHostActivity {
private static final String TAG="MainActivity";
List<TabItem> mItems; //list什么作用
@Override
protected void prepare() {
Log.i(TAG, "prepare--");
TabItem home = new TabItem(
this.getResources().getString(R.string.home), // title
R.drawable.icon_home, // icon
R.drawable.example_tab_item_bg, // background
new Intent(this, Tab1Activity.class)); // intent
TabItem msg = new TabItem(
this.getResources().getString(R.string.msg),
R.drawable.icon_meassage,
R.drawable.example_tab_item_bg,
new Intent(this, Tab1Activity.class));
TabItem setting = new TabItem(
this.getResources().getString(R.string.setting),
R.drawable.icon_square,
R.drawable.example_tab_item_bg,
new Intent(this, Tab1Activity.class));
TabItem feedback = new TabItem(
this.getResources().getString(R.string.feedback),
R.drawable.icon_selfinfo,
R.drawable.example_tab_item_bg,
new Intent(this, Tab1Activity.class));
mItems = new ArrayList<TabItem>();
mItems.add(home);
mItems.add(msg);
mItems.add(setting);
mItems.add(feedback);
//
TabWidget tabWidget = getTabWidget();
tabWidget.setDividerDrawable(R.drawable.tab_divider);
getLayoutInflater();
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.i(TAG, "---------this is MainAcitvity--------");
setCurrentTab(0);
}
@Override
protected void setTabItemTextView(TextView textView, int position) {
Log.i(TAG, "setTabItemTextView");
textView.setPadding(3, 3, 3, 3);
textView.setText(mItems.get(position).getTitle());
textView.setBackgroundResource(mItems.get(position).getBg());
textView.setCompoundDrawablesWithIntrinsicBounds(0, mItems.get(position).getIcon(), 0, 0);
}
@Override
protected String getTabItemId(int position) {
Log.i(TAG, "getTabItemId");
return mItems.get(position).getTitle(); //鑾峰彇褰撳墠ID
}
@Override
protected Intent getTabItemIntent(int position) {
Log.i(TAG, "getTabItemIntent");
return mItems.get(position).getIntent();
}
@Override
protected int getTabItemCount() {
Log.i(TAG, "getTabItemCount");
return mItems.size();
}
}
这里就重写了我们在框架类(tabhostActivity类)中定义的抽象函数,实现了功能,估计大家也应该看出些端倪,为什么我们会在框架类中进行定义。
此时我们就实现了底部tabhost UI框架设计。