首页 > 代码库 > 创建TabHost的两种方式的简单分析
创建TabHost的两种方式的简单分析
最近做了一个TabHost的界面,在做的过程中发现了一些问题,故和大家分享一下。
首先我的界面如下:
目前就我所知,创建TabHost有两种方式,第一种是继承TabActivity类,然后用getTabHost方法来得到一个TabHost的实例,然后就可以给这个TabHost添加Tab了。示例代码如下:
- public class PlotHost extends TabActivity {
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- // TODO Auto-generated method stub
- super.onCreate(savedInstanceState);
- // setContentView(R.layout.activity_main);
- setContentView(R.layout.tabhost);
- Resources res=getResources();
- TabHost tabhost=getTabHost();
- TabSpec dynamicplotSpec;
- TabSpec staticplotSpec;
- Intent dynamicplotIntent;
- Intent staticplotIntent;
- View dynamicplotView;
- View staticplotView;
- dynamicplotIntent=new Intent(this,Tab1.class);
- dynamicplotView=new TabView(this, R.drawable.dynamicploto, R.drawable.dynamicplots, "动态曲线");
- dynamicplotSpec=tabhost.newTabSpec("DynamicplotTab");
- dynamicplotSpec.setIndicator(dynamicplotView).setContent(dynamicplotIntent);
- tabhost.addTab(dynamicplotSpec);
- staticplotSpec=tabhost.newTabSpec("StaticplotTab");
- staticplotView=new TabView(this, R.drawable.staticploto, R.drawable.staticplots, "历史曲线");
- staticplotIntent=new Intent(this,Tab2.class);
- staticplotSpec.setIndicator(staticplotView).setContent(staticplotIntent);
- tabhost.addTab(staticplotSpec);
- tabhost.setCurrentTab(0);
- }
- //自定义一个tab选项卡显示样式
- private class TabView extends LinearLayout {
- ImageView imageView ;
- public TabView(Context c, int drawableSelected, int drawableUnselected,String label) {
- super(c);
- this.setOrientation(VERTICAL);
- imageView = new ImageView(c);
- StateListDrawable listDrawable = new StateListDrawable();
- listDrawable.addState(SELECTED_STATE_SET, this.getResources()
- .getDrawable(drawableSelected));
- listDrawable.addState(ENABLED_STATE_SET, this.getResources()
- .getDrawable(drawableUnselected));
- imageView.setImageDrawable(listDrawable);
- imageView.setBackgroundColor(Color.TRANSPARENT);
- setGravity(Gravity.CENTER);
- addView(imageView);
- TextView tv_label=new TextView(c);
- tv_label.setText(label);
- tv_label.setGravity(Gravity.CENTER);
- addView(tv_label);
- }
- }
- }
具体代码我就不用多分析,只需要提一点的就是,用这种方式根本就不用你自定义一个TabHost的组建,getTabHost方法会自动调用系统默认的布局来帮助你进行显示,所以代码里面使用setContentView是多余的。
第二种方式问题就比较多了,其中网上大部分都说直接集成Activity,然后使用findViewbyId找到自定义的TabHost的组件,最后对这个TabHost调用setup方法即可。但是不知道是何原因,也许是我的API版本比较高的原因,使用这种方法始终没有成功,logcat里面报java.lang.RuntimeException异常。最后google后发现,需要改一下方式,即继承ActivityGroup,然后最后setup的时候需要使用setup(this.getLocalActivityManager)即可,代码如下:
- public class PlotHost extends ActivityGroup {
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- // TODO Auto-generated method stub
- super.onCreate(savedInstanceState);
- // setContentView(R.layout.activity_main);
- setContentView(R.layout.tabhost);
- Resources res=getResources();
- TabHost tabhost=(TabHost)findViewById(R.id.tabhost);
- tabhost.setup(this.getLocalActivityManager());
- TabSpec dynamicplotSpec;
- TabSpec staticplotSpec;
- Intent dynamicplotIntent;
- Intent staticplotIntent;
- View dynamicplotView;
- View staticplotView;
- dynamicplotIntent=new Intent(this,Tab1.class);
- dynamicplotView=new TabView(this, R.drawable.dynamicploto, R.drawable.dynamicplots, "动态曲线");
- dynamicplotSpec=tabhost.newTabSpec("DynamicplotTab");
- dynamicplotSpec.setIndicator(dynamicplotView).setContent(dynamicplotIntent);
- tabhost.addTab(dynamicplotSpec);
- staticplotSpec=tabhost.newTabSpec("StaticplotTab");
- staticplotView=new TabView(this, R.drawable.staticploto, R.drawable.staticplots, "历史曲线");
- staticplotIntent=new Intent(this,Tab2.class);
- staticplotSpec.setIndicator(staticplotView).setContent(staticplotIntent);
- tabhost.addTab(staticplotSpec);
- tabhost.setCurrentTab(0);
- }
- //自定义一个tab选项卡显示样式
- private class TabView extends LinearLayout {
- ImageView imageView ;
- public TabView(Context c, int drawableSelected, int drawableUnselected,String label) {
- super(c);
- this.setOrientation(VERTICAL);
- imageView = new ImageView(c);
- StateListDrawable listDrawable = new StateListDrawable();
- listDrawable.addState(SELECTED_STATE_SET, this.getResources()
- .getDrawable(drawableSelected));
- listDrawable.addState(ENABLED_STATE_SET, this.getResources()
- .getDrawable(drawableUnselected));
- imageView.setImageDrawable(listDrawable);
- imageView.setBackgroundColor(Color.TRANSPARENT);
- setGravity(Gravity.CENTER);
- addView(imageView);
- TextView tv_label=new TextView(c);
- tv_label.setText(label);
- tv_label.setGravity(Gravity.CENTER);
- addView(tv_label);
- }
- }
- }
其实内容大同小异,至于为什么要这么做,貌似是如果直接调用TabHost的setup方法,不能实例化它的TabWidget和TabContent对象,需要借助于LocalActivityManager自动对二者进行实例化。因为看了一个老兄的博客,setup主要完成的功能便是实例化它的TabWidget和TabContent。如下:
mTabWidget = (TabWidget) findViewById(com.android.internal.R.id.tabs);
if (mTabWidget == null) {
throw new RuntimeException(
"Your TabHost must have a TabWidget whose id attribute is ‘android.R.id.tabs‘");
}
mTabContent = (FrameLayout) findViewById(com.android.internal.R.id.tabcontent);
if (mTabContent == null) {
throw new RuntimeException(
"Your TabHost must have a FrameLayout whose id attribute is ‘android.R.id.tabcontent‘");
}
同时,还要补充,使用第二种方法的时候注意修改TabHost在布局当中的ID格式为“@+id/xxx”,其中xxx自定义。其他的步骤在网上一搜一大堆我就不唠叨了。
创建TabHost的两种方式的简单分析