上篇内容讲一些比较基本和简单的用法,这篇稍微说一些相对来来说比较高级一点的用法。
数据传递
举例来讲:当前页面上有一个EditText用于接收用户输入信息,当点击一个按钮,开启下一个页面,并在写个页面显示用户所输入的文字,怎么做?
这就涉及到了Activity之间数据传递。
而通过Intent就可以做到这个功能,查看官方API发现Intent有一个putExtra的方法,接收很多种数据类型,如图:
接收的参数其实是以key,value的形式,第一个参数接收一个String字符串,第二个参数代表要传递的数据类型。在Activity之间传输的数据类型有基本类型、数组、Bundle、Serializable对象、Parcelable对象等。
话不多说,上代码。
package com.mesmerize.activitytest;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
/**
* Created by mesmerize on 16/9/16.
*/
public class InputActivity extends Activity implements View.OnClickListener {
private EditText et_input;
private String inputContent;
private Button btn_click;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_input);
initView();
initListener();
}
/**
* 初始化View控件
*/
private void initView() {
et_input = (EditText) findViewById(R.id.et_input);
btn_click = (Button) findViewById(R.id.btn_click);
}
/**
* 获取用户输入的文字信息
*/
private void fillData() {
inputContent = et_input.getText().toString();
}
private void initListener() {
btn_click.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_click:
skipActivity();
break;
}
}
private void skipActivity() {
fillData();
Intent intent = new Intent(InputActivity.this,AcceptActivity.class);
intent.putExtra("transfer", inputContent);
startActivity(intent);
}
}
xml文件没什么可说的,就一个TextView一个EditText还有一个Button
当我输入“Hello Activity”
这个时候我点击按钮会执行skipActivity() 这个方法,可以看到我给intent塞了一条数据
接下来看AcceptActivity的代码:
package com.mesmerize.activitytest;
import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
/**
* Created by mesmerize on 16/9/16.
*/
public class AcceptActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_accept);
String data = getData();
TextView tv_accept = (TextView) findViewById(R.id.tv_accept);
tv_accept.setText(data);
}
/**
* 获取上个页面传递过来的数据
*/
private String getData() {
// 注意,这个key千万不能写错,它是跟上个页面所写的key一一对应的
String transfer = getIntent().getStringExtra("transfer");
return transfer;
}
}
其实这个代码很简单,就是获取上个页面intent里传过来的一个key的名为“transfer”的数据,取到这个数据之后放入TextView里面展示出来。
除了传递String,还可以传很多很多的类型
Intent intent = new Intent(this, 目标Activity.class);
Bundle b1 = new Bundle();
b1.putString("name", "亚索");
b1.putInt("age", 25);
Bundle b2 = new Bundle();
b2.putString("name", "劫");
b2.putInt("age", 33);
intent.putExtra("b1", b1);
intent.putExtra("b2", b2);
// 比如传递一个对象
Intent intent = new Intent(this, 目标Activity.class);
Person p = new Person("艾克", 44);
intent.putExtra("p", p);
以上就是一个简单的数据传递的一个示例
数据回传
有些时候我们会遇到数据回传的需求,比如下订单时填写收货地址信息或者例如发帖子时要附带一些图片,进入图库选择好照片后,会返回到发表状态页面并带回所选的图片信息等等等等,这些在开发中是很常见的。而如果我们要实现这种需求该怎么做呢?
发现官方文档上有这么个介绍:
Sometimes, you might want to receive a result from the activity that you start. In that case, start the activity by calling startActivityForResult() (instead of startActivity()). To then receive the result from the subsequent activity, implement the onActivityResult() callback method. When the subsequent activity is done, it returns a result in an Intent to your onActivityResult() method.
原来启动Activity不仅仅只有一个startActivity(),还有一个启动的方式叫startActivityForResult()。
当要实现数据回传的时候可以利用startActivityForResult()这种方法来替代startActivity。还要实现onActivityResult()这个回调方法。
废话不多说,上代码:
这是第一个Activity
package com.mesmerize.activitytest;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
/**
* Created by mesmerize on 16/9/16.
*/
public class FirstActivity extends Activity implements View.OnClickListener {
private TextView tv_result;
private Button btn_skip;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_first);
initView();
initListener();
}
/**
* 初始化View控件
*/
private void initView(){
tv_result = (TextView) findViewById(R.id.tv_result);
btn_skip = (Button) findViewById(R.id.btn_skip);
}
private void initListener(){
btn_skip.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.btn_skip:
skipActivity();
break;
}
}
/**
* 开启下一个Activity
*/
private void skipActivity(){
Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
// param2 意味请求码,是一个int值
startActivityForResult(intent,1);
}
/**
* Activity数据的回传 为了拿到传回的数据 必须在源Activity中重写onActivityResult
* @param requestCode 请求码 即调用startActivityForResult()传递过去的int值
* @param resultCode 结果码 结果码用于标识返回数据来自哪个新Activity
*/
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (data != null) {
switch (requestCode) {
case 1:
String result = data.getStringExtra("result");
tv_result.setText("回传的数据是: "+ result);
break;
}
}
}
}
很简单,就是一个很简单的两个控件
看下一个Activity,当点击按钮开启一个新的Activity
代码如下:
package com.mesmerize.activitytest;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
/**
* Created by mesmerize on 16/9/16.
*/
public class SecondActivity extends Activity implements View.OnClickListener {
private Button btn_finish;
private EditText et_input;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
initView();
initListener();
}
private void initView() {
et_input = (EditText) findViewById(R.id.et_input);
btn_finish = (Button) findViewById(R.id.btn_finish);
}
private void initListener() {
btn_finish.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_finish:
passbackResult();
break;
}
}
/**
* 点击按钮,将输入的文字回传到上个Activity中去
*/
private void passbackResult() {
// 获取EditText中所输入的内容
String content = et_input.getText().toString();
// 数据使用Intent进行回传
Intent intent = new Intent();
// 将输入的内容放入intent中去
intent.putExtra("result", content);
// 设置返回数据 RESULT_OK是一个int值 除此之外 还有RESULT_CANCELED / RESULT_FIRST_USER
setResult(RESULT_OK,intent);
// 关闭当前Activity
finish();
}
}
当我输入一段文字之后,比如我输入“Ha SA Ki”,然后点击输入完毕,回传数据…
看代码就是:关闭当前Activity,并且把当前EditText上所输入的内容放到Intent中,返回给上一个Activity,即FirstActivity。
这个就是一个很简单的数据回传的示例。
讲一讲requestCode(请求码)和resultCode(结果码)的作用
requestCode 请求码
使用startActivityForResult(Intent intent, int requestCode)方法打开新的Activity,我们需要为startActivityForResult()方法传入一个请求码(第二个参数)。请求码的值是根据业务需要由自已设定,用于标识请求来源。
举例来说:比如一个Activity有两个按钮A和B,点击这两个按钮都会打开同一个Activity,不管是A按钮还是B按钮打开新Activity,当这个新Activity关闭后,系统都会调用前面Activity的onActivityResult(int requestCode, int resultCode, Intent data)方法。在onActivityResult()方法我们需要知道回传的数据由A按钮还是B按钮打开的,并且要做出相应的业务处理,这时就可以这样做:
@Override
public void onCreate(Bundle savedInstanceState) {
....
btn_a.setOnClickListener(new View.OnClickListener(){
public void onClick(View v) {
Intent firstIntent = new Intent(FirstActivity.this, SecondActivity.class);
// 请求码为1
startActivityForResult (firstIntent, 1);
}
});
btn_b.setOnClickListener(new View.OnClickListener(){
public void onClick(View v) {
Intent secondIntent = new Intent(FirstActivity.this, SecondActivity.class);
// 请求码为2
startActivityForResult (secondIntent, 2);
}
});
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// 以请求码为判断依据
switch(requestCode){
case 1:
//来自按钮A的请求,作相应业务处理
break;
case 2:
//来自按钮B的请求,作相应业务处理
break;
}
}
}
细细想一下,其实这个工作中是很有用的。
讲完了请求码,再讲讲结果码。
resultCode 结果码
在一个Activity中,可能会使用startActivityForResult()方法打开多个不同的Activity处理不同的业务,当这些新Activity关闭后,系统都会调用前面Activity的onActivityResult(int requestCode, int resultCode, Intent data)方法。为了知道返回的数据来自于哪个新Activity,在onActivityResult()方法中可以这样做(SecondActivity和ThreeActivity为要打开的新Activity):
public class SecondActivity extends Activity {
.....
SecondActivity.this.setResult(1, intent);
SecondActivity.this.finish();
}
public class ThreeActivity extends Activity {
......
ThreeActivity.this.setResult(2, intent);
ThreeActivity.this.finish();
}
public class FirstActivity extends Activity { // 在该Activity会打开SecondActivity和ThreeActivity
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// 以结果码为判断依据
switch(resultCode){
case 1:
// SecondActivity的返回数据
break;
case 2:
// ThreeActivity的返回数据
break;
}
}
}