标签/TabActivity 深度研究

本文将介绍如何通过自定义TabActivity实现美观的标签栏,包括在XML和Java中定义标签布局,更改标签样式及监听切换事件,并提供代码示例及运行效果对比。

何谓标签 印象最深刻的应该是这个

现在 我们将通过一系列的扩展来研究之

写道
1. 自定义TabActivity 使得标签处于屏幕下方
2. 各个标签所用布局 既可在 *.xml 中定义 也可在 *.java 中定义
3. 更改标签布局

1. 标签页 在 屏幕下方

写道
一个典型的标签Activity 是由2 部分构成的 且其id都有规定 即:
* TabWidget 用于展示标签页 id=tabs
* FrameLayout 用于展示隶属于各个标签的具体布局 id=tabcontent

* 基本布局如下:

Xml代码 复制代码 收藏代码
  1. <?xmlversion="1.0"encoding="utf-8"?>
  2. <TabHostxmlns:android="http://schemas.android.com/apk/res/android"
  3. android:id="@android:id/tabhost"
  4. android:layout_width="fill_parent"
  5. android:layout_height="fill_parent">
  6. <LinearLayout
  7. android:orientation="vertical"
  8. android:gravity="bottom"
  9. android:layout_width="fill_parent"
  10. android:layout_height="fill_parent">
  11. <FrameLayout
  12. android:id="@android:id/tabcontent"
  13. android:layout_width="fill_parent"
  14. android:layout_height="200dip">
  15. <RelativeLayout
  16. android:id="@+id/view1"
  17. android:orientation="vertical"
  18. android:layout_width="fill_parent"
  19. android:layout_height="fill_parent"
  20. >
  21. <TextView
  22. android:id="@+id/text"
  23. android:layout_width="wrap_content"
  24. android:layout_height="wrap_content"
  25. android:text="HellotoJohnny.Griffin!"
  26. android:layout_centerInParent="true"
  27. android:textStyle="bold|italic"/>
  28. <ImageView
  29. android:layout_width="fill_parent"
  30. android:layout_height="fill_parent"
  31. android:src="@drawable/robot"
  32. android:layout_toLeftOf="@id/text"/>
  33. </RelativeLayout>
  34. <TextView
  35. android:id="@+id/view2"
  36. android:layout_width="fill_parent"
  37. android:layout_height="fill_parent"
  38. android:text="创新源于模仿!"/>
  39. <TextView
  40. android:id="@+id/view3"
  41. android:layout_width="fill_parent"
  42. android:layout_height="fill_parent"
  43. android:text="欢迎进入droid世界!"/>
  44. <ImageView
  45. android:id="@+id/view4"
  46. android:layout_width="fill_parent"
  47. android:layout_height="fill_parent"
  48. android:src="@drawable/robot"/>
  49. </FrameLayout>
  50. <TabWidget
  51. android:id="@android:id/tabs"
  52. android:layout_width="fill_parent"
  53. android:layout_height="wrap_content"/>
  54. </LinearLayout>
  55. </TabHost>
<?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:gravity="bottom" android:layout_width="fill_parent" android:layout_height="fill_parent" > <FrameLayout android:id="@android:id/tabcontent" android:layout_width="fill_parent" android:layout_height="200dip" > <RelativeLayout android:id="@+id/view1" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <TextView android:id="@+id/text" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Hello to Johnny.Griffin!" android:layout_centerInParent="true" android:textStyle="bold|italic" /> <ImageView android:layout_width="fill_parent" android:layout_height="fill_parent" android:src="@drawable/robot" android:layout_toLeftOf="@id/text" /> </RelativeLayout> <TextView android:id="@+id/view2" android:layout_width="fill_parent" android:layout_height="fill_parent" android:text="创新源于模仿!" /> <TextView android:id="@+id/view3" android:layout_width="fill_parent" android:layout_height="fill_parent" android:text="欢迎进入 droid 世界!" /> <ImageView android:id="@+id/view4" android:layout_width="fill_parent" android:layout_height="fill_parent" android:src="@drawable/robot" /> </FrameLayout> <TabWidget android:id="@android:id/tabs" android:layout_width="fill_parent" android:layout_height="wrap_content" /> </LinearLayout> </TabHost>

* 得到TabHost tHost 仅在TabActivity中有效

Java代码 复制代码 收藏代码
  1. tHost=this.getTabHost();
tHost = this.getTabHost();

* 创建4个标签 并指定所使用的布局

Java代码 复制代码 收藏代码
  1. publicstaticfinalStringTab1="Tab1";
  2. publicstaticfinalStringTab2="Tab2";
  3. publicstaticfinalStringTab3="Tab3";
  4. publicstaticfinalStringTab4="Tab4";
  5. publicstaticfinalStringTab5="Tab5";
  6. tHost.addTab(tHost.newTabSpec(Tab1).setIndicator("Tab1",getResources().getDrawable(R.drawable.icon)).setContent(R.id.view1));
  7. tHost.addTab(tHost.newTabSpec(Tab2).setIndicator("Tab2",getResources().getDrawable(R.drawable.beijing_small)).setContent(R.id.view2));
  8. tHost.addTab(tHost.newTabSpec(Tab3).setIndicator("Tab3").setContent(R.id.view3));
  9. tHost.addTab(tHost.newTabSpec(Tab4).setIndicator("Tab4").setContent(R.id.view4));
public static final String Tab1 = "Tab1"; public static final String Tab2 = "Tab2"; public static final String Tab3 = "Tab3"; public static final String Tab4 = "Tab4"; public static final String Tab5 = "Tab5"; tHost.addTab(tHost.newTabSpec(Tab1).setIndicator("Tab 1", getResources().getDrawable(R.drawable.icon)).setContent(R.id.view1)); tHost.addTab(tHost.newTabSpec(Tab2).setIndicator("Tab 2", getResources().getDrawable(R.drawable.beijing_small)).setContent(R.id.view2)); tHost.addTab(tHost.newTabSpec(Tab3).setIndicator("Tab 3").setContent(R.id.view3)); tHost.addTab(tHost.newTabSpec(Tab4).setIndicator("Tab 4").setContent(R.id.view4));

* 设定监听器 用于监听 标签间切换事件

Java代码 复制代码 收藏代码
  1. tHost.setOnTabChangedListener(newOnTabChangeListener(){
  2. @Override
  3. publicvoidonTabChanged(StringtabId){
  4. //TODOAuto-generatedmethodstub
  5. }
  6. });
tHost.setOnTabChangedListener(new OnTabChangeListener(){ @Override public void onTabChanged(String tabId) { // TODO Auto-generated method stub } });

* emulator 运行情况:

2. 在 *.java 中定义标签所需布局

Java代码 复制代码 收藏代码
  1. publicclassCustomLayoutimplementsTabHost.TabContentFactory{
  2. Activityactivity;
  3. LayoutInflaterinflaterHelper;
  4. LinearLayoutlayout;
  5. publicCustomLayout(Activitya){
  6. activity=a;
  7. inflaterHelper=a.getLayoutInflater();
  8. }
  9. /**{@inheritDoc}*///tag标记各个标签
  10. publicViewcreateTabContent(Stringtag){
  11. returnaddCustomView(tag);
  12. }
  13. publicViewaddCustomView(Stringid){
  14. layout=newLinearLayout(activity);
  15. layout.setOrientation(LinearLayout.VERTICAL);
  16. if(id.equals(Tab1)){
  17. ImageViewiv=newImageView(activity);
  18. iv.setImageResource(R.drawable.beijing_big);
  19. layout.addView(iv,
  20. newLinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT,LinearLayout.LayoutParams.FILL_PARENT));
  21. }
  22. elseif(id.equals(Tab2)){
  23. EditTextedit=newEditText(activity);
  24. layout.addView(edit,
  25. newLinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT,LinearLayout.LayoutParams.FILL_PARENT));
  26. Buttonbtn=newButton(activity);
  27. btn.setText("OK");
  28. btn.setWidth(100);
  29. layout.addView(btn,
  30. newLinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT,LinearLayout.LayoutParams.FILL_PARENT));
  31. RadioGrouprGroup=newRadioGroup(activity);
  32. rGroup.setOrientation(LinearLayout.HORIZONTAL);
  33. RadioButtonradio1=newRadioButton(activity);
  34. radio1.setText("RadioA");
  35. rGroup.addView(radio1);
  36. RadioButtonradio2=newRadioButton(activity);
  37. radio2.setText("RadioB");
  38. rGroup.addView(radio2);
  39. layout.addView(rGroup,
  40. newLinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,LinearLayout.LayoutParams.WRAP_CONTENT));
  41. }
  42. elseif(id.equals(Tab3)){
  43. LinearLayout.LayoutParamsparam3=
  44. newLinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT,LinearLayout.LayoutParams.FILL_PARENT);
  45. layout.addView(inflaterHelper.inflate(R.layout.hello,null),param3);
  46. }
  47. elseif(id.equals(Tab4)){
  48. TextViewtv=newTextView(activity);
  49. tv.setText("HelloTags!");
  50. tv.setGravity(Gravity.CENTER);
  51. layout.addView(tv);
  52. }
  53. returnlayout;
  54. }
  55. }
public class CustomLayout implements TabHost.TabContentFactory { Activity activity; LayoutInflater inflaterHelper; LinearLayout layout; public CustomLayout (Activity a) { activity = a; inflaterHelper = a.getLayoutInflater(); } /** {@inheritDoc} *///tag 标记各个标签 public View createTabContent(String tag) { return addCustomView(tag); } public View addCustomView(String id){ layout = new LinearLayout(activity); layout.setOrientation(LinearLayout.VERTICAL); if(id.equals(Tab1)){ ImageView iv = new ImageView(activity); iv.setImageResource(R.drawable.beijing_big); layout.addView(iv, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.FILL_PARENT)); } else if(id.equals(Tab2)){ EditText edit = new EditText(activity); layout.addView(edit, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.FILL_PARENT)); Button btn = new Button(activity); btn.setText("OK"); btn.setWidth(100); layout.addView(btn, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.FILL_PARENT)); RadioGroup rGroup = new RadioGroup(activity); rGroup.setOrientation(LinearLayout.HORIZONTAL); RadioButton radio1 = new RadioButton(activity); radio1.setText("Radio A"); rGroup.addView(radio1); RadioButton radio2 = new RadioButton(activity); radio2.setText("Radio B"); rGroup.addView(radio2); layout.addView(rGroup, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT)); } else if(id.equals(Tab3)){ LinearLayout.LayoutParams param3 = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.FILL_PARENT); layout.addView(inflaterHelper.inflate(R.layout.hello, null),param3); } else if(id.equals(Tab4)){ TextView tv = new TextView(activity); tv.setText("HelloTags!"); tv.setGravity(Gravity.CENTER); layout.addView(tv); } return layout; } }

* 如何使用:

Java代码 复制代码 收藏代码
  1. CustomLayoutct=newCustomLayout(this);
  2. tHost.addTab(tHost.newTabSpec(Tab4).setIndicator("Tab4").setContent(ct));
CustomLayout ct = new CustomLayout(this); tHost.addTab(tHost.newTabSpec(Tab4).setIndicator("Tab 4").setContent(ct));

* emulator 运行结果:

3. 改变标签布局

写道
可能很多人对TabActivity 不满意 原因之一:其很不美观 而不美观的根源就是:标签的问题 其图像和文字相互覆盖 导致的


那么 我们可以自己扩展么? 当然

写道
TabWidget 理解:

1. TabWidget 为 horizontal 的 LinearLayout
2. 且 其包含的标签又是一个RelativeLayout
3. 每个标签RelativeLayout 里面包含2个View: TextView ImageView

因此 我们甚至可以推算出其布局为:

Java代码 复制代码 收藏代码
  1. <?xmlversion="1.0"encoding="utf-8"?>
  2. <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
  3. android:orientation="horizontal"
  4. android:layout_width="fill_parent"
  5. android:layout_height="fill_parent"
  6. >
  7. <RelativeLayout
  8. android:orientation="vertical"
  9. android:layout_width="fill_parent"
  10. android:layout_height="wrap_content">
  11. <ImageView/>
  12. <TextView/>
  13. </RelativeLayout>
  14. <RelativeLayout
  15. android:orientation="vertical"
  16. android:layout_width="fill_parent"
  17. android:layout_height="wrap_content">
  18. <ImageView/>
  19. <TextView/>
  20. </RelativeLayout>
  21. <RelativeLayout
  22. android:orientation="vertical"
  23. android:layout_width="fill_parent"
  24. android:layout_height="wrap_content">
  25. <ImageView/>
  26. <TextView/>
  27. </RelativeLayout>
  28. <RelativeLayout
  29. android:orientation="vertical"
  30. android:layout_width="fill_parent"
  31. android:layout_height="wrap_content">
  32. <ImageView/>
  33. <TextView/>
  34. </RelativeLayout>
  35. </LinearLayout>
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:layout_width="fill_parent" android:layout_height="fill_parent" > <RelativeLayout android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="wrap_content"> <ImageView /> <TextView /> </RelativeLayout> <RelativeLayout android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="wrap_content"> <ImageView /> <TextView /> </RelativeLayout> <RelativeLayout android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="wrap_content"> <ImageView /> <TextView /> </RelativeLayout> <RelativeLayout android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="wrap_content"> <ImageView /> <TextView /> </RelativeLayout> </LinearLayout>

* 去掉系统默认的布局 即 在 setIndicator() 中置空 修改如下:

Java代码 复制代码 收藏代码
  1. tHost.addTab(tHost.newTabSpec(Tab1).setIndicator("").setContent(ct));
tHost.addTab(tHost.newTabSpec(Tab1).setIndicator("").setContent(ct));

写道
可能有人会说:那我不调用setIndicator() 不久可以了么 不行 否则 会报错

* 自己定义布局 并 指定显示的内容

Java代码 复制代码 收藏代码
  1. publicViewcomposeLayout(Strings,inti){
  2. LinearLayoutlayout=newLinearLayout(this);
  3. layout.setOrientation(LinearLayout.VERTICAL);
  4. TextViewtv=newTextView(this);
  5. tv.setGravity(Gravity.CENTER);
  6. tv.setSingleLine(true);
  7. tv.setText(s);
  8. layout.addView(tv,
  9. newLinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT,LinearLayout.LayoutParams.WRAP_CONTENT));
  10. ImageViewiv=newImageView(this);
  11. iv.setImageResource(i);
  12. layout.addView(iv,
  13. newLinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT,LinearLayout.LayoutParams.WRAP_CONTENT));
  14. returnlayout;
  15. }
public View composeLayout(String s, int i){ LinearLayout layout = new LinearLayout(this); layout.setOrientation(LinearLayout.VERTICAL); TextView tv = new TextView(this); tv.setGravity(Gravity.CENTER); tv.setSingleLine(true); tv.setText(s); layout.addView(tv, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT)); ImageView iv = new ImageView(this); iv.setImageResource(i); layout.addView(iv, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT)); return layout; }

* 得到 TabWidget 实例 tw

Java代码 复制代码 收藏代码
  1. LinearLayoutll=(LinearLayout)tHost.getChildAt(0);
  2. tw=(TabWidget)ll.getChildAt(1);
LinearLayout ll=(LinearLayout)tHost.getChildAt(0); tw =(TabWidget)ll.getChildAt(1);

* 得到 TabWidget 内的具体某个Layout 并使用上面的布局 composeLayout()

Java代码 复制代码 收藏代码
  1. publicvoidupdateWidgetView(inti,Stringtext,intimage){
  2. RelativeLayoutrl=(RelativeLayout)tw.getChildAt(i);
  3. rl.addView(composeLayout(text,image));
  4. }
public void updateWidgetView(int i,String text,int image){ RelativeLayout rl =(RelativeLayout)tw.getChildAt(i); rl.addView(composeLayout(text,image)); }

* emulator 运行截图 // 前面 3个是使用新布局 最后一个是使用TabActivity 默认的布局 哪个好看 大家自己选择之

that's all!

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值