关于TabActivity,也就不介绍了,本文只介绍更深入更有趣到内容,了解的知识请Google、Baidu之。本文主要内容是:TabActivity的生命周期、Tab间的跳转以及其它Activity到Tab的跳转等,
首先研究下TabActivity及其子Activity的生命周期,,首先这是个蛮有趣到现象,也蛮值得研究,为了测试,我准备了以下的类:
1、TabActivityActivity extends TabActivity ,程序启动Activity
2、HomeActivity、SearchActivity extends Activity分别是两个Tab页面
3、SearchChildActivity extends Activity ,由 SearchActivity --(跳转)--->SearchChildActivity
同时,为了后续的使用,我也把整个程序的大致界面都做了,简要截图如下:
我们分别在Activity的各个生命周期的方法里分别打印出调试消息,具体如下(以其中1个Activity为例,其他类似)
package org.lansir; import android.app.Activity; import android.content.Intent; import android.content.IntentFilter; import android.os.Bundle; import android.util.Log; public class HomeActivity extends BaseActivity { public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.home); Log.v("test", "home onCreate"); } @Override protected void onDestroy() { super.onDestroy(); Log.v("test", "home onDestroy"); } @Override protected void onNewIntent(Intent intent) { super.onNewIntent(intent); Log.v("test", "home onNewIntent"); } @Override protected void onPause() { super.onPause(); Log.v("test", "home onPause"); } @Override protected void onRestart() { super.onRestart(); Log.v("test", "home onRestart"); } @Override protected void onResume() { super.onResume(); Log.v("test", "home onResume"); } @Override protected void onStart() { super.onStart(); Log.v("test", "home onStart"); } @Override protected void onStop() { super.onStop(); Log.v("test", "home onStop"); } }
准备材料完毕,开始测试。我们分别从启动、Tab之间跳转、Tab和其它Activity之间跳转3个方面去测试。
1、Activity启动
看到这个,刚开始觉得很正常,因为TabActivity先创建是毫无疑问的,但是接下来居然是home先onStart,我之前的想法是
但现在是tab:onCreate()->tab:onStart()->tab:onResume()->home:onCreate->home:onStart->home:onResume
tab:onCreate()->home:onCreate->home:onStart->tab:onStart()->tab:onResume()->home:onResume
俺有点不解,具体原因还有待解释,等改天看下源代码再解读之,也请各位大侠赐教。
2、Tab之间跳转
这里有个很有趣的现象,我们知道,我们在TabActivity把各Tab添加进去的时候代码一般是这么写的,以本文为例如下:
Intent layout1intent = new Intent(); layout1intent.setClass(this, HomeActivity.class); TabHost.TabSpec layout1spec = mTabHost.newTabSpec("home"); layout1spec.setIndicator("home"); layout1spec.setContent(layout1intent); mTabHost.addTab(layout1spec); Intent layout2intent = new Intent(); layout2intent.setClass(this, SearchActivity.class); TabHost.TabSpec layout2spec = mTabHost.newTabSpec("search"); layout2spec.setContent(layout2intent); layout2spec.setIndicator("search"); mTabHost.addTab(layout2spec);如上,一般是在newSpec的时候,一个填home,一个填search,但如果两者填一样呢,会如何?我们把mTabHost.newTabSpec的参数都写成"home",尝试下,发现了一个非常不一样的地方!此时,俺无法用语言来表达俺激动的心情,但为了更好的理解,还是请各位耐心的看下来,俺也从基本开始,解释为啥这个不一样。我们先从正常情况下开始(即在newSpec的时候,一个填home,一个填search)
从HomeActivity跳转到SearchActivity(第一次):
此时,由于Search第一次创建,因此要onCreate
从SearchActivity跳转到HomeActivity(第一次):
这时由于之前home已经创建过,所以并没有销毁,直接search:onPause->home:onResume
从HomeActivity跳转到SearchActivity(第二次):
从SearchActivity跳转到HomeActivity(第二次):
另外一种情况,(即在newSpec的时候,两个都填相同的值),测试结果如下:也就是,各个Tab只有在第一次显示时才创建---即调用onCreate方法,在其他时候,Tab之间的切换只是在onPause和onResume中切换而已
从HomeActivity跳转到SearchActivity(第一次):
我们再看看从SearchActivity跳转到HomeActivity(第一次):
从HomeActivity跳转到SearchActivity(第二次):
从SearchActivity跳转到HomeActivity(第二次):
大家仔细观察!有木有发现!!!有木有!!!有木有!!!在这种情况下,Tab之间的切换过程中,每个Tab销毁掉重新创建!!并且在这个过程中,TabActivity一直处于onResume状态。每个Tab都经历了
onCreate->onStart->onResume->onPause->onStop->onDestroy
3、Tab和其它Activity之间跳转
我们从SearchActivity进入SearchChildActivity
返回:
跟正常的Activity之间的跳转没啥两样
以上就是对TabActivity及Tab的声明周期的测试及探索,各位大虾有新的发现也分享于小弟下。
(2)Tab间的跳转以及子Activity的跳转
这也是网上议论比较多的一个话题,一般情况下程序要有tab的话,我们一般都是使用TabActivity,但是这种方法在初学的过程中,我们会遇到一个问题:如果tab之间有数据进行交互我们要如何去做?tab之间要进行切换?从一个tab跳回到Activity A,再跳到Activity B,然后要从Activity B返回TabActivity( 即我们常见的Home菜单功能)?于是新手在碰到这些问题的时候总是很困扰,往往采用一种很笨拙的形式去做。一般我们要使用Tab的时候,有两种方法1、TabActivity,这种比较适用于Tab间无通讯的情况2、自己模拟TabActivity:使用自定义按钮代替TabWidget,并使用addView和removeView实现Tab之间的切换,这里不具体解释。这种方式适用于操作性比较高、Tab之间通讯等情况,但是有个复杂的地方,就是可能要在各个View之间模拟Activiyt的生命周期:如view1在下载,view2在聊天,按home键,它们俩的状态要保存住。由于公司的项目适合于第一种情况,自己也顺便也探索了这种方法。探索之一:Tab之间如何跳转1、使用BroadcastReceiver即在TabActivity中注册一个BroadcastReceiver,然后当tab要跳转的时候,发送一个broadcast,TabActivity在接收后进行tab的切换但这种方法麻烦,占用系统资源,如果没有设置BroadcastReceiver的优先级时,响应缓慢2、利用Activity的launchMode特性一般情况下,我们在使用TabActivity的时候,一般是要求这个TabActivity在当前程序中是 唯一的!也就是:当跳到这个TabActivity时,如果Task栈中有这个Activity,就会使用这个Activity。这与Activity的launchMode中的singleTask的处理方式是一样的,在这个时候,在TabActivity之上的栈中的元素都会被弹出栈外,当然,一般情况下,这与我们的业务也是相符的。因此,我们在Tab间的跳转就可以直接通过 startActivity()方法进行跳转~!我们以本文的例子为例:我们要实现从SearchActivity跳转到HomeActivity,可如下实现:1、修改AndroidManifest.xml中TabActivity的lanuchMode<activity android:name=".TabActivityActivity" android:label="@string/app_name" android:launchMode="singleTask"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity>
2、TabActivity.java 中添加如下方法@Override protected void onNewIntent(Intent intent) { super.onNewIntent(intent); int tabIndex = intent.getIntExtra(INTENT_TAB_CHANGE, -1); if(tabIndex != -1 ){ getTabHost().setCurrentTab(tabIndex); } Log.v("test", "TabActivity onNewIntent"); }
PS:为什么要实现onNewIntent呢?这个跟singleTask有关,当Activity A的launchMode为singleTask时,如果该Activity A已经存在,那么Activity B跳转到Activity A的时候,intent之间的传递只能通过onNewIntent,无法通过onStart,onResume等方法。(可到官方文档查看)
3、在SearchActivity中定义按钮跳转到HomeActivity的事件((Button)findViewById(R.id.btn_search2)).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(SearchActivity.this, TabActivityActivity.class); intent.putExtra(TabActivityActivity.INTENT_TAB_CHANGE, TabActivityActivity.TAB_INDEX_HOME); startActivity(intent); } });
TAB_INDEX_HOME是HomeAcivity的index,这样,就可以实现从一个Tab跳转到另外一个Tab了
探索之二:其他Activity到Tab的跳转比较经典的一个使用场景,就是在程序的“Home菜单”,即在任何Activity中,点击Home菜单,返回主页
1、使用onActivityResult
即希望能够在TabActivity中获取其他Activity的resultCode,事实证明这种方法是 不可行的! 因为TabActivity无法获取,只能是Tab去获取。有人说:那我可以在Tab获取,然后在通过 探索之一的第二种方式返回呀?这是典型的冗余,我们可以直接跳到TabActivity去,这就是我们将要介绍的另一种方法。2、利用Activity的launchMode特性
其实就跟探索之一的第二种方式一样,直接使用startActivity(),传入要跳转的Tab的index即可
Intent intent = new Intent(this, TabActivityActivity.class); intent.putExtra(TabActivityActivity.INTENT_TAB_CHANGE, TabActivityActivity.TAB_INDEX_HOME); startActivity(intent);
到此为止,对TabActivity的探索就告一段落了,希望能够通过这次探索跟大家分享更多的Android开发知识,也希望大家能多交流。
案例代码:http://download.csdn.net/source/3480493。
版权所有,转载请出明出处!