Android: Tab的使用总结之前在t.sina.com.cn/kevinlynx陆续贴了些android开发涉及到的一些code snippets,
Android: Tab的使用总结
之前在t.sina.com.cn/kevinlynx陆续贴了些android开发涉及到的一些code snippets,主要目的是记录,供以后需要的时候查阅方便。但是因为miniblog的字数限制,在记录较多信息的时候还是有诸多不便。so, i'm here.
Tab view算是我接触android平台第二个比较迷惑的地方(第一个是ListView的adapter)。在百度了一些别人的使用心得/总结后,依然发现对tab view的使用存在很多疑问。包括ApiDemo里的例子以及其他一些例子代码。就目前而言我依然存在部分疑点,不过,就单纯的使用而言,倒是足够了。
Tab view通过TabHost来管理tab page:
A TabHost is(copyed from official reference):
Container for a tabbed window view. This object holds two children: a set of tab labels that the user clicks to select a specific tab, and a FrameLayout object that displays the contents of that page.
使用TabHost必然涉及到TabActivity:
class TabSample extends TabActivity { protected void onCreate( Bundle savedInstanceState ) { TabHost tabHost = getTabHost(); }};取得TabHost 更多地是为tab添加page,即标签页。
此外,android用TabSpec来表示一个标签页,可以通过tabHost.newTabSpec来创建,创建的时候一般会立即设置各种属性,如下代码:
tabHost.addTab(tabHost.newTabSpec("tab1") .setIndicator("tab1") .setContent(R.id.view1));添加标签页的方式就多了,方式太多正是迷惑人的地方。就我目前所查阅的资料来看,有3个方式添加子标签(添加子标签即为tab setContent):
1、如ApiDemo Tabs1.java所示,使用layout (declared in xml)来作为内容:
LayoutInflater.from(this).inflate(R.layout.tabs1, tabHost.getTabContentView(), true); tabHost.addTab(tabHost.newTabSpec("tab1") .setIndicator("tab1") .setContent(R.id.view1));这里的inflate实际上我不太理解,好像是将tabs1这个layout实力化为java对象,并作为tabHost.getTabContentView()的子views。inflat相关机制还没去研究。
2、如ApiDemo Tabs2.java所示,使用TabHost.TabContentFactory来设置标签页的内容:
public class Tabs2 extends TabActivity implements TabHost.TabContentFactory { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); final TabHost tabHost = getTabHost(); tabHost.addTab(tabHost.newTabSpec("tab1") .setIndicator("tab1", getResources().getDrawable(R.drawable.star_big_on)) .setContent(this)); .... public View createTabContent(String tag) { final TextView tv = new TextView(this); tv.setText("Content for tab with tag " + tag); return tv; }3、我想这才是我目前所需要的方式,直接嵌入其他的Activity进来。通过Intent的方式,如ApiDemo Tabs3.java所示:
protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); final TabHost tabHost = getTabHost(); tabHost.addTab(tabHost.newTabSpec("tab1") .setIndicator("list") .setContent(new Intent(this, List1.class))); ....以上几种方式中,只有方式1需要使用一个layout(我的意思是xml配置的)。在我查看的另一份代码中(UROP1,一个闹钟程序),他使用了第三种方式,但却在开头setContentView。在我注释掉这行代码时,效果依然没变。包括在网上的很多其他文章,都会使用setContentView,但看起来有点多余。这也是让我迷惑的地方。
综合来说,三种方式,都不需要setContentView,方式1需要inflat一份layout,其他2种则不需要。
BTW,Javaeye的blog编辑功能还不错。:D
1.2.2011 update
默认设置下,TabActivity中的content是activity的话,第一次切换会触发onCreate,切换标签页
不会导致当前activity onStop/onDestroy,只有当退出TabActivity时,才触发。
标签页切换会导致子activity onPause,只有当前处于前台的activity,才会接收到
onBackPressed,整个TabActivity退出时,只会触发一次finishedFromChild。
1 楼 jowett 2011-08-12 尝试了一把,不使用tabhost,单独使用LayoutInflater.from(this).inflate(R.layout.xx, learlayout, true);
可以把layout.xx的内容作为learlayout的child,并显示出来。也就是说这个函数其实和tabhost的实现没有什么具体的关系。
实际上使用了
LayoutInflater.from(this).inflate(R.layout.tabs1, tabHost.getTabContentView(), true);
以后,相当于把tabs1下面所有的内容放在tabWidget下面作为child,但是因为默认第一个tab页会被set focus,所以页面马上又变为tab1所指向的第一个View1了
