《Google Android SDK开发范例大全》第3章为大家讲述的是用户人机界面,本节为大家介绍返回数据到前一个Activity。
3.11 返回数据到前一个Activity
startActivityForResult方法
范例说明
上一个范例中,好不容易将数据从Activity1传递至Activity2,如果要再回到Activity1,数据该不会要再封装一次吧?而且前一个Activity1早就被程序destroy了,倘若在Activity1最后以finish() 结束程序,再通过Activity2将数据采用Bundle的方式通过新打开Activity1传递参数,这样的做法虽然也可以恢复User输入的数据,但是并不符合我们的期待,尤其是User曾经输入过的数据,如果不小心点击回到上一页,数据就消失不见,这就不妙了。
有鉴于科技始终来自于人性,如果要在次页面加上一个"回上页"的按钮,而非通过模拟器的回复键,且回上页后又能保留之前输入的相关信息,那么就必须使用startActivityForResult()来唤起一个Activity。利用这个方法,前一个Activity1便会有一个等待次Activity2的返回,而返回的数据就可以达到我们想要的结果。
运行结果
范例程序
- src/irdc.ex03_11/EX03_11.java
在Activity1主程序中调用Activity的方法更改成startActivityForResult(intent,0),其中0为下一个Activity要返回值的依据,可指定为自行定义的参考标识符(Identifier)。程序覆盖了onActivityResult() 这个方法,令程序在收到result后,再重新加载写回原本输入的值。
- package irdc.ex03_11;
- /* import相关class */
- import android.app.Activity;
- import android.content.Intent;
- import android.os.Bundle;
- import android.view.View;
- import android.widget.Button;
- import android.widget.EditText;
- import android.widget.RadioButton;
- public class EX03_11 extends Activity
- {
- private EditText et;
- private RadioButton rb1;
- private RadioButton rb2;
- /** Called when the activity is first created. */
- @Override
- public void onCreate(Bundle savedInstanceState)
- {
- super.onCreate(savedInstanceState);
- /* 载入main.xml Layout */
- setContentView(R.layout.main);
- /* 以findViewById()取得Button对象,并添加onClickListener */
- Button b1 = (Button) findViewById(R.id.button1);
- b1.setOnClickListener(new Button.OnClickListener()
- {
- public void onClick(View v)
- {
- /*取得输入的身高*/
- et = (EditText) findViewById(R.id.height);
- double height=Double.parseDouble(et.getText().toString());
- /*取得选择的性别*/
- String sex="";
- rb1 = (RadioButton) findViewById(R.id.sex1);
- rb2 = (RadioButton) findViewById(R.id.sex2);
- if(rb1.isChecked())
- {
- sex="M";
- }
- else
- {
- sex="F";
- }
- /*new一个Intent对象,并指定class*/
- Intent intent = new Intent();
- intent.setClass(EX03_11.this,EX03_11_1.class);
- /*new一个Bundle对象,并将要传递的数据传入*/
- Bundle bundle = new Bundle();
- bundle.putDouble("height",height);
- bundle.putString("sex",sex);
- /*将Bundle对象assign给Intent*/
- intent.putExtras(bundle);
- /*调用Activity EX03_11_1*/
- startActivityForResult(intent,0);
- }
- });
- }
- /* 覆盖 onActivityResult()*/
- @Override
- protected void onActivityResult(int requestCode, int resultCode,
- Intent data)
- {
- switch (resultCode)
- {
- case RESULT_OK:
- /* 取得来自Activity2的数据,并显示于画面上 */
- Bundle bunde = data.getExtras();
- String sex = bunde.getString("sex");
- double height = bunde.getDouble("height");
- et.setText(""+height);
- if(sex.equals("M"))
- {
- rb1.setChecked(true);
- }
- else
- {
- rb2.setChecked(true);
- }
- break;
- default:
- break;
- }
- }
- }
src/irdc.ex03_11/EX03_11_1.java
在Activity2的主程序中,设计当Button被点击时,将Bundle对象与结果返回给前一个Activity1。
- package irdc.ex03_11;
- /* import相关class */
- import java.text.DecimalFormat;
- import java.text.NumberFormat;
- import android.app.Activity;
- import android.content.Intent;
- import android.os.Bundle;
- import android.view.View;
- import android.widget.Button;
- import android.widget.TextView;
- public class EX03_11_1 extends Activity
- {
- Bundle bunde;
- Intent intent;
- /** Called when the activity is first created. */
- @Override
- public void onCreate(Bundle savedInstanceState)
- {
- super.onCreate(savedInstanceState);
- /* 载入mylayout.xml Layout */
- setContentView(R.layout.myalyout);
- /* 取得Intent中的Bundle对象 */
- intent=this.getIntent();
- bunde = intent.getExtras();
- /* 取得Bundle对象中的数据 */
- String sex = bunde.getString("sex");
- double height = bunde.getDouble("height");
- /* 判断性别 */
- String sexText="";
- if(sex.equals("M"))
- {
- sexText="男性";
- }
- else
- {
- sexText="女性";
- }
- /* 取得标准体重 */
- String weight=this.getWeight(sex, height);
- /* 设置输出文字 */
- TextView tv1=(TextView) findViewById(R.id.text1);
- tv1.setText("你是一位"+sexText+"\n你的身高是"+height+
- "厘米\n你的标准体重是"+weight+"公斤");
- /* 以findViewById()取得Button对象,并添加onClickListener */
- Button b1 = (Button) findViewById(R.id.button1);
- b1.setOnClickListener(new Button.OnClickListener()
- {
- public void onClick(View v)
- {
- /* 返回result回上一个activity */
- EX03_11_1.this.setResult(RESULT_OK, intent);
- /* 结束这个activity */
- EX03_11_1.this.finish();
- }
- });
- }
- /* 四舍五入的method */
- private String format(double num)
- {
- NumberFormat formatter = new DecimalFormat("0.00");
- String s=formatter.format(num);
- return s;
- }
- /* 以findViewById()取得Button对象,并添加onClickListener */
- private String getWeight(String sex,double height)
- {
- String weight="";
- if(sex.equals("M"))
- {
- weight=format((height-80)*0.7);
- }
- else
- {
- weight=format((height-70)*0.6);
- }
- return weight;
- }
- }
res/layout/mylayout.xml
mylayout.xml为Activity2(EX03_11_1)的Layout,其中定义了显示计算结果的TextView与回上一页的Button按钮。
- <?xml version="1.0" encoding="utf-8"?>
- <AbsoluteLayout
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- xmlns:android="http://schemas.android.com/apk/res/android"
- >
- <TextView
- android:id="@+id/text1"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:textSize="20sp"
- android:layout_x="50px"
- android:layout_y="72px"
- >
- </TextView>
- <Button
- android:id="@+id/button1"
- android:layout_width="100px"
- android:layout_height="48px"
- android:text="回上一页"
- android:layout_x="110px"
- android:layout_y="180px"
- >
- </Button>
- </AbsoluteLayout>
AndroidManifest.xml
范例中有两个Activity,所以AndroidManifest.xml里必须有这两个activity的声明,否则系统将无法运行。
- <?xml version="1.0" encoding="utf-8"?>
- <manifest
- xmlns:android="http://schemas.android.com/apk/res/android"
- package="irdc.ex03_11"
- android:versionCode="1"
- android:versionName="1.0.0">
- <application
- android:icon="@drawable/icon"
- android:label="@string/app_name">
- <activity
- android:name=".EX03_11"
- android:label="@string/app_name">
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.LAUNCHER" />
- </intent-filter>
- </activity>
- <activity android:name="EX03_11_1"></activity>
- </application>
- </manifest>
扩展学习
范例中为了在回到上一页时,能够显示之前所输入的数据,故将原本传递次Activity的Intent(里面包含了有数据的Bundle对象)再重新返回给主Activity1。如果要在次Activity2中返回其它的数据,例如,经过计算后的结果、数据,此时只需将要返回的数据再放入Bundle对象中即可达成。
此外,以本范例而言,其实使用startActivity()也可达成同样的结果,仅需在主Activity被create时去判断Intent内有没有数据,有的话,就将数据带入;没有的话,就带入空值(null)。但程序还需要再做有无值的比较,较为繁琐,既然Android API中有提供更好用的方法,何来不用的道理?更何况如果系统不是只有几行代码,而是几十行、几百行代码,那时头可就大了!