转 TabActivity探索 .

来源:互联网 发布:看门狗2唐人街重要数据 编辑:程序博客网 时间:2024/04/29 21:16
最近在做项目的时候,由于公司使用到TabActivity去做分页,之前自己一直是使用自定义按钮去做分页的。既然公司使用TabActivity,索性也就用它去尝试下跳转及探索下其他功能。


关于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


同时,为了后续的使用,我也把整个程序的大致界面都做了,简要截图如下:


(一)TabActivity的生命周期

我们分别在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");}@Overrideprotected void onDestroy() {super.onDestroy();Log.v("test", "home onDestroy");}@Overrideprotected void onNewIntent(Intent intent) {super.onNewIntent(intent);Log.v("test", "home onNewIntent");}@Overrideprotected void onPause() {super.onPause();Log.v("test", "home onPause");}@Overrideprotected void onRestart() {super.onRestart();Log.v("test", "home onRestart");}@Overrideprotected void onResume() {super.onResume();Log.v("test", "home onResume");}@Overrideprotected void onStart() {super.onStart();Log.v("test", "home onStart");}@Overrideprotected 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(第二次):



也就是,各个Tab只有在第一次显示时才创建---即调用onCreate方法,在其他时候,Tab之间的切换只是在onPause和onResume中切换而已

另外一种情况,(即在newSpec的时候,两个都填相同的值),测试结果如下:

从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

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。


	
				
		
原创粉丝点击