TabActivity探索

最近在做项目的时候,由于公司使用到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探索_第1张图片


(一)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");
	}

	@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(第二次):



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

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

从HomeActivity跳转到SearchActivity(第一次):

TabActivity探索_第2张图片

我们再看看从SearchActivity跳转到HomeActivity(第一次):

TabActivity探索_第3张图片

从HomeActivity跳转到SearchActivity(第二次):

TabActivity探索_第4张图片

从SearchActivity跳转到HomeActivity(第二次):

TabActivity探索_第5张图片

大家仔细观察!有木有发现!!!有木有!!!有木有!!!在这种情况下,Tab之间的切换过程中,每个Tab销毁掉重新创建!!并且在这个过程中,TabActivity一直处于onResume状态。每个Tab都经历了

onCreate->onStart->onResume->onPause->onStop->onDestroy

3、Tab和其它Activity之间跳转

我们从SearchActivity进入SearchChildActivity

TabActivity探索_第6张图片

返回:

TabActivity探索_第7张图片

跟正常的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。


版权所有,转载请出明出处!








   

你可能感兴趣的:(android,测试,layout,search,button,通讯)