页面跳转即数据传递

创建第二个界面Acivity

*需要在清单文件中添加配置一个Actuvity标签

  • 标签中如果带有这个子节点,则会在Android中添加一个快捷图标
<intent-filter>
       <action android:name="android.intent.action.MAIN" />
       <category android:name="android.intent.category.LAUNCHER" />
   </intent-filter>
  • 另外需要创建出第二个界面还需要在第二节界面中书写代码
setContentView(R.layout.activity_second);
  • 在 创建第二个快捷图标可以了解到我们可以在同一个application中创建多个图标分别表示同一个applicatilon中的不同界面快捷图标

Activity的跳转

Activity的跳转需要创建Intent对象,通过设置Intent对象的参数指定要跳转的Activity

通过设置Activity的包名和类名实现跳转,称为显式意图

通过指定动作实现跳转,称为隐式跳转

显示意图

  • 清单文件设置
  • 在跳转至同一个项目下的另一个Activity,直接指定该Activity的字节码即可
Intent intent = new Intent();  //定义意图
  intent.setClass(this, SecondActivity.class);
  startActivity(intent);
  • 跳转至其他应用中的Activity,需要指定该应用的包名和该Activity的类名
Intent intent = new Intent();
  //启动系统自带的拨号器应用
  intent.setClassName("com.android.dialer", "com.android.dialer.DialtactsActivity");
  startActivity(intent);

隐式意图

  • 隐式意图跳转至指定Activity
Intent intent = new Intent();
  //启动系统自带的拨号器应用
  intent.setAction(Intent.ACTION_DIAL);
  startActivity(intent);
  • 要让一个Activity可以被隐式启动,需要在清单文件的activity节点中设置intent-filter子节点
<intent-filter >
      <action android:name="com.itheima.second"/>
      <data android:scheme="asd" android:mimeType="aa/bb"/>
      <category android:name="android.intent.category.DEFAULT"/>
  </intent-filter>
  
  * action 指定动作(可以自定 义,可以使用系统自带的)
  * data   指定数据(操作什么内容)
  * category 类别 (默认类别,机顶盒,车载电脑)
  • 隐式意图启动Activity,需要intent设置三个以上属性,且必须与该Activity在清单文件中对应的三个属性定义一一匹配
  • intent-filter节点及其子节点都可以同时定义多个,隐式启动时只需与任意一个匹配即可

获取通过setData传递的数据

  • Activity通过Intent启动时,可以通过Intent对象携带数据到目标Activity
  • 在目标Activity中取出数据
Intent intent = getIntent();
  //从intent对象中把封装好的数据取出来
  //String maleName = intent.getStringExtra("malename");
  //String feMaleName = intent.getStringExtra("femalename");
  
  Bundle bundle = intent.getExtras();
  String maleName = bundle.getString("malename");
  String feMaleName = bundle.getString("femalename");
  
  Random rd = new Random();
  int yinyuan = rd.nextInt(100);
  
  TextView tv = (TextView) findViewById(R.id.tv);
  tv.setText(maleName + "和" + feMaleName + "的姻缘值为" + yinyuan);

生命周期

void onCreate()

  • Activity已经被创建完毕

void onStart()

  • Activity已经显示在屏幕,但没有得到焦点

void onResume()

  • Activity得到焦点,可以与用户交互

void onPause()

  • Activity失去焦点,无法再与用户交互,但依然可见

void onStop()

  • Activity不可见,进入后台

void onDestroy()

  • Activity被销毁

void onRestart()

  • Activity从不可见变成可见时会执行此方法

使用场景

  • Activity创建时需要初始化资源,销毁时需要释放资源;或者播放器应用,在界面进入后台时需要自动暂停

完整生命周期(entire lifetime)

  • onCreate-->onStart-->onResume-->onPause-->onStop-->onDestory

可视生命周期(visible lifetime)

  • onStart-->onResume-->onPause-->onStop

前台生命周期(foreground lifetime)

  • onResume-->onPause

Activity的四种启动模式

  • 每个应用会有一个Activity任务栈,存放已启动的Activity

Activity的启动模式

SingleTop 单一顶部模式: 如果任务栈的栈顶存在这个要开启的Activity,不会重新创建Activity,而是复用已经存在的Activity,如果栈顶存在则不会再次创建
singleTask 单一任务栈 : 在当前任务栈中只能存在一个实例,如果有实例存在就复用这个已经存在的Activity,并且把这个Activity上面的Activity全部清空,复用这个已经存在的Activity,使得任务栈中只有一个实例存在,这种任务栈可应用在浏览器当中。如果一个Activity的创建需要占用大量的系统资源,但是又可以在多个应用中关联启动时,可以使用这种启动模式。webkit内核 c代码
singleInstance启动模式 : singleInstance启动模式非常特殊,Activity会运行在自己的任务栈里面,并且这个任务栈里面只有一个实例存在。如果要使得整个手机操作系统中只有一个实例存在,使用singleInstance启动模式。应用场景:电话拨打界面

横竖屏界面切换是的生命周期

  • 默认的情况下,横竖屏切换的Activity,会使得原Activity销毁后重新创建新的Activity后显示
  • 横竖屏在模拟器中切换使用 : CTRL+F11
  • 在有些应用的需求中不能进行默认的横竖屏切换时关闭原有的界面在重新创建新的界面,这是可以使用代码将横竖屏写死:
在Manifest里对于的activity加上这个配置就不会重走销毁和创建了,如下:

	android:configChanges="orientation|keyboardHidden|screenSize"
  • 解决方法:针对横竖屏不同的布局,我们只需在创建一个layout-land文件夹,里面放同名的布局文件,onCreate时会自动加载相对应的横竖屏布局。 在横竖屏切换的过程中会经历onSaveInstanceState,给你一个保存数据的机会:
@Override
  public void onSaveInstanceState(Bundle outState) {
  	    Log.i("linc", "onSaveInstanceState(Bundle)");
  	    super.onSaveInstanceState(outState);

      outState.putString(TEXT_ONE, ""+editText1.getTag(R.id.tag_first));//>avoid null point
  	//outState.putSerializable();//object
  }
*然后将数据取出来
@Override
  protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
   setContentView(R.layout.activity_land_port_switch);
   Log.e("linc","oncreate");
   editText1 = (EditText)findViewById(R.id.txt1);
           // Restore saved state.
        if (savedInstanceState != null) {            
            editText1.setTag(R.id.tag_first,savedInstanceState.getString(TEXT_ONE));
        }
   }    	protected void onCreate(Bundle savedInstanceState) {
   super.onCreate(savedInstanceState);
   setContentView(R.layout.activity_land_port_switch);
   Log.e("linc","oncreate");
   editText1 = (EditText)findViewById(R.id.txt1);
           // Restore saved state.
       if (savedInstanceState != null) {            
             editText1.setTag(R.id.tag_first,savedInstanceState.getString(TEXT_ONE));
       }
   }

掌握开启Activity获取返回值

从A界面跳转到B界面,B界面关闭的时候返回带着数据给A界面

  • 跳转页面并且开启 Activity 并且获取返回值
//跳转至选择联系人Activity
	Intent intent = new Intent(this, ContactActivity.class);
	//用这个api启动的Activity,在销毁时,系统会回调onActivityResult
	startActivityForResult(intent, 10);
  • 在新开启的界面里实现数据的逻辑
ListView lv = (ListView) findViewById(R.id.lv);
	
	final String[] objects = new String[]{
			"小志,教教我泡妞",
			"逼哥,带我飞吧",
			"世界就在我的脚下",
			"国服打野第一"
	};
	
	//将objects数组中的数据显示在页面中
	lv.setAdapter(new ArrayAdapter<String>(this, R.layout.item_listview, R.id.tv, objects));

	//给listview设置条目的点击侦听
	lv.setOnItemClickListener(new OnItemClickListener() {

		//当某个条目被点击时,此方法调用
		@Override
		public void onItemClick(AdapterView<?> parent, View view,
				int position, long id) {
			
			//Activity返回时传递数据,也是通过意图对象
			Intent data = new Intent();
			//把要传递的数据封装至意图对象中
			data.putExtra("name", objects[position]);
			
			//当前Activity销毁时,data这个意图就会传递给启动当前Activity的那个Activity
			setResult(1, data);
			
			//销毁当前Activity
			finish();
		}
	});
  • 在开启者的Activity里面实现方法
//如果有Activity在销毁时返回了数据,那么就会调用此方法来接收数据
	//requestCode:用来区分数据来自于哪一个Activity
	//resultCode:用来区分返回的数据是什么类型的
	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {

		super.onActivityResult(requestCode, resultCode, data);
	
		String name = data.getStringExtra("name");
		if(requestCode == 10){
			EditText et = (EditText)findViewById(R.id.et);
			et.setText(name);
		}
		
		else if(requestCode == 20){
			EditText et_content = (EditText)findViewById(R.id.et_content);
			et_content.setText(name);
		}
	}
  • 如果同一个界面返回的数据有多种,可以根据结果吗进行区分,然后实现不同的操作