创建TabHost的两种方式的简单分析


最近做了一个TabHost的界面,在做的过程中发现了一些问题,故和大家分享一下。

首先我的界面如下:


目前就我所知,创建TabHost有两种方式,第一种是继承TabActivity类,然后用getTabHost方法来得到一个TabHost的实例,然后就可以给这个TabHost添加Tab了。示例代码如下:

[java] view plaincopy
  1. publicclassPlotHostextendsTabActivity{
  2. @Override
  3. protectedvoidonCreate(BundlesavedInstanceState){
  4. //TODOAuto-generatedmethodstub
  5. super.onCreate(savedInstanceState);
  6. //setContentView(R.layout.activity_main);
  7. setContentView(R.layout.tabhost);
  8. Resourcesres=getResources();
  9. TabHosttabhost=getTabHost();
  10. TabSpecdynamicplotSpec;
  11. TabSpecstaticplotSpec;
  12. IntentdynamicplotIntent;
  13. IntentstaticplotIntent;
  14. ViewdynamicplotView;
  15. ViewstaticplotView;
  16. dynamicplotIntent=newIntent(this,Tab1.class);
  17. dynamicplotView=newTabView(this,R.drawable.dynamicploto,R.drawable.dynamicplots,"动态曲线");
  18. dynamicplotSpec=tabhost.newTabSpec("DynamicplotTab");
  19. dynamicplotSpec.setIndicator(dynamicplotView).setContent(dynamicplotIntent);
  20. tabhost.addTab(dynamicplotSpec);
  21. staticplotSpec=tabhost.newTabSpec("StaticplotTab");
  22. staticplotView=newTabView(this,R.drawable.staticploto,R.drawable.staticplots,"历史曲线");
  23. staticplotIntent=newIntent(this,Tab2.class);
  24. staticplotSpec.setIndicator(staticplotView).setContent(staticplotIntent);
  25. tabhost.addTab(staticplotSpec);
  26. tabhost.setCurrentTab(0);
  27. }
  28. //自定义一个tab选项卡显示样式
  29. privateclassTabViewextendsLinearLayout{
  30. ImageViewimageView;
  31. publicTabView(Contextc,intdrawableSelected,intdrawableUnselected,Stringlabel){
  32. super(c);
  33. this.setOrientation(VERTICAL);
  34. imageView=newImageView(c);
  35. StateListDrawablelistDrawable=newStateListDrawable();
  36. listDrawable.addState(SELECTED_STATE_SET,this.getResources()
  37. .getDrawable(drawableSelected));
  38. listDrawable.addState(ENABLED_STATE_SET,this.getResources()
  39. .getDrawable(drawableUnselected));
  40. imageView.setImageDrawable(listDrawable);
  41. imageView.setBackgroundColor(Color.TRANSPARENT);
  42. setGravity(Gravity.CENTER);
  43. addView(imageView);
  44. TextViewtv_label=newTextView(c);
  45. tv_label.setText(label);
  46. tv_label.setGravity(Gravity.CENTER);
  47. addView(tv_label);
  48. }
  49. }
  50. }

具体代码我就不用多分析,只需要提一点的就是,用这种方式根本就不用你自定义一个TabHost的组建,getTabHost方法会自动调用系统默认的布局来帮助你进行显示,所以代码里面使用setContentView是多余的。


第二种方式问题就比较多了,其中网上大部分都说直接集成Activity,然后使用findViewbyId找到自定义的TabHost的组件,最 后对这个TabHost调用setup方法即可。但是不知道是何原因,也许是我的API版本比较高的原因,使用这种方法始终没有成功,logcat里面报 java.lang.RuntimeException异常。最后google后发现,需要改一下方式,即继承ActivityGroup,然后最后 setup的时候需要使用setup(this.getLocalActivityManager)即可,代码如下:

[java] view plaincopy
  1. publicclassPlotHostextendsActivityGroup{
  2. @Override
  3. protectedvoidonCreate(BundlesavedInstanceState){
  4. //TODOAuto-generatedmethodstub
  5. super.onCreate(savedInstanceState);
  6. //setContentView(R.layout.activity_main);
  7. setContentView(R.layout.tabhost);
  8. Resourcesres=getResources();
  9. TabHosttabhost=(TabHost)findViewById(R.id.tabhost);
  10. tabhost.setup(this.getLocalActivityManager());
  11. TabSpecdynamicplotSpec;
  12. TabSpecstaticplotSpec;
  13. IntentdynamicplotIntent;
  14. IntentstaticplotIntent;
  15. ViewdynamicplotView;
  16. ViewstaticplotView;
  17. dynamicplotIntent=newIntent(this,Tab1.class);
  18. dynamicplotView=newTabView(this,R.drawable.dynamicploto,R.drawable.dynamicplots,"动态曲线");
  19. dynamicplotSpec=tabhost.newTabSpec("DynamicplotTab");
  20. dynamicplotSpec.setIndicator(dynamicplotView).setContent(dynamicplotIntent);
  21. tabhost.addTab(dynamicplotSpec);
  22. staticplotSpec=tabhost.newTabSpec("StaticplotTab");
  23. staticplotView=newTabView(this,R.drawable.staticploto,R.drawable.staticplots,"历史曲线");
  24. staticplotIntent=newIntent(this,Tab2.class);
  25. staticplotSpec.setIndicator(staticplotView).setContent(staticplotIntent);
  26. tabhost.addTab(staticplotSpec);
  27. tabhost.setCurrentTab(0);
  28. }
  29. //自定义一个tab选项卡显示样式
  30. privateclassTabViewextendsLinearLayout{
  31. ImageViewimageView;
  32. publicTabView(Contextc,intdrawableSelected,intdrawableUnselected,Stringlabel){
  33. super(c);
  34. this.setOrientation(VERTICAL);
  35. imageView=newImageView(c);
  36. StateListDrawablelistDrawable=newStateListDrawable();
  37. listDrawable.addState(SELECTED_STATE_SET,this.getResources()
  38. .getDrawable(drawableSelected));
  39. listDrawable.addState(ENABLED_STATE_SET,this.getResources()
  40. .getDrawable(drawableUnselected));
  41. imageView.setImageDrawable(listDrawable);
  42. imageView.setBackgroundColor(Color.TRANSPARENT);
  43. setGravity(Gravity.CENTER);
  44. addView(imageView);
  45. TextViewtv_label=newTextView(c);
  46. tv_label.setText(label);
  47. tv_label.setGravity(Gravity.CENTER);
  48. addView(tv_label);
  49. }
  50. }
  51. }

其实内容大同小异,至于为什么要这么做,貌似是如果直接调用TabHost的setup方法,不能实例化它的TabWidget和TabContent对象,需要借助于LocalActivityManager自动对二者进行实例化。因为看了一个老兄的博客,setup主要完成的功能便是实例化它的TabWidget和TabContent。如下:

mTabWidget=(TabWidget)findViewById(com.android.internal.R.id.tabs);
if(mTabWidget==null){
thrownewRuntimeException(
"YourTabHostmusthaveaTabWidgetwhoseidattributeis'android.R.id.tabs'");
}

mTabContent=(FrameLayout)findViewById(com.android.internal.R.id.tabcontent);
if(mTabContent==null){
thrownewRuntimeException(
"YourTabHostmusthaveaFrameLayoutwhoseidattributeis'android.R.id.tabcontent'");
}

同时,还要补充,使用第二种方法的时候注意修改TabHost在布局当中的ID格式为“@+id/xxx”,其中xxx自定义。其他的步骤在网上一搜一大堆我就不唠叨了。

优质内容筛选与推荐>>
1、An internal error occurred during: "Launching ****"
2、MySQL主从复制(Master-Slave)与读写分离(MySQL-Proxy)实践
3、在技术文档中偶尔出现的拉丁文
4、DOS常用命令
5、dpkg -i packagename.deb;安装 .deb包


长按二维码向我转账

受苹果公司新规定影响,微信 iOS 版的赞赏功能被关闭,可通过二维码转账支持公众号。

    阅读
    好看
    已推荐到看一看
    你的朋友可以在“发现”-“看一看”看到你认为好看的文章。
    已取消,“好看”想法已同步删除
    已推荐到看一看 和朋友分享想法
    最多200字,当前共 发送

    已发送

    朋友将在看一看看到

    确定
    分享你的想法...
    取消

    分享想法到看一看

    确定
    最多200字,当前共

    发送中

    网络异常,请稍后重试

    微信扫一扫
    关注该公众号





    联系我们

    欢迎来到TinyMind。

    关于TinyMind的内容或商务合作、网站建议,举报不良信息等均可联系我们。

    TinyMind客服邮箱:support@tinymind.net.cn