多个Activity之间的相互调用:
新建一个继承Activity的类,在功能清单AndroidManifest.xml文件中添加进上面Activity配置代码,
打开新的Activity:startActivity(new Intent(MainActivity.this, NewActivity.class));
打开新的Activity,并传递若干个参数给它:
Intent intent = newIntent(MainActivity.this, NewActivity.class)
Bundle bundle = new Bundle();//该类用作携带数据
bundle.putString("name", "传智播客");
bundle.putInt("age", 4);
intent.putExtras(bundle);//附带上额外的数据
startActivity(intent);
在另一个Activity里面接收参数:
Bundle bundle = this. getIntent_r().getExtras_r();
String name = bundle.getString_r("name");
int age = bundle. getInt_r("age");
Bundle类用作携带数据,它类似于Map,用于存放key-value名值对形式的值。相对于Map,它提供了各种常用类型的putXxx()/ getXxx_r()方法,如:putString()/getString_r()和putInt()/getInt_r(),putXxx()用于往Bundle对象放入数据, getXxx_r()方法用于从Bundle对象里获取数据。Bundle的内部实际上是使用了HashMap类型的变量来存放putXxx()方法放入的值:
请求码的作用:
使用startActivityForResult(Intent intent, intrequestCode)方法打开新的Activity,我们需要为startActivityForResult()方法传入一个请求码(第二个参数)。请求码的值是根据业务需要由自已设定,用于标识请求来源。例如:一个Activity有两个按钮,点击这两个按钮都会打开同一个Activity,不管是那个按钮打开新Activity,当这个新Activity关闭后,系统都会调用前面Activity的onActivityResult(int requestCode, int resultCode, Intent data)方法。在onActivityResult()方法如果需要知道新Activity是由那个按钮打开的,并且要做出相应的业务处理。
结果码的作用:
在一个Activity中,可能会使用startActivityForResult()方法打开多个不同的Activity处理不同的业务,当这些新Activity关闭后,系统都会调用前面Activity的onActivityResult(int
Activity跳转与传值,主要是通过Intent类来连接多个Activity,以及传递数据。
Intent是Android一个很重要的类。Intent直译是“意图”,什么是意图呢?比如你想从这个Activity跳转到另外一个Activity,这就是一个意图。Intent类在Android系统中的作用很大,在此不详细说了,后面有文章介绍!
Activity跳转,无返回结果
这是最简单的Activity跳转方式。从一个Activity启动另一个Activity,直接startActivity(new Intent(当前Activity.this,下一Activity.class))。
1 ((Button)findViewById(R.id.Notepadv1)).setOnClickListener( new OnClickListener() {
2 public void onClick(View v) {
3 startActivity(new Intent (MyAndroidAppActivity.this,Notepadv1.class) );
4 }
5 });
Activity跳转,返回数据/结果
需要返回数据或结果的,则使用startActivityForResult (Intent intent, intrequestCode)
,requestCode的值是自定义的,用于识别跳转的目标Activity。
跳转的目标Activity所要做的就是返回数据/结果,setResult(int resultCode)只返回结果不带数据,或者setResult(int resultCode, Intent data)两者都返回!
而接收返回的数据/结果的处理函数是onActivityResult(int requestCode, int resultCode, Intent data),这里的requestCode就是startActivityForResult的requestCode,resultCode就是setResult里面的resultCode,返回的数据在data里面。
MyAndroidAppActivity:
6 static final intSEND_SMS_REQUEST = 0;
7 static final intCALL_REQUEST = 1;
8
9 ((Button)findViewById(R.id.sms)).setOnClickListener( new OnClickListener() {
10 public void onClick(View v) {
11 Intent intent = newIntent(MyAndroidAppActivity.this, SendSMSActivity.class);
12 startActivityForResult(intent,SEND_SMS_REQUEST);
13 }
14 });
15
16 @Override
17 protected voidonActivityResult(int requestCode, int resultCode, Intent data) {
18 if (requestCode == SEND_SMS_REQUEST) {
19 if (resultCode == RESULT_OK) {
20 Toast.makeText(this, "Send SMSRESULT_OK", Toast.LENGTH_SHORT).show();
21 }else if (resultCode ==RESULT_CANCELED) {
22 Bundle bundle = data.getExtras();
23 String phoneno =bundle.getString("phoneNO");
24 Toast.makeText(this, "Send SMSRESULT_CANCELED "+phoneno, Toast.LENGTH_SHORT).show();
25 }
26 }else if (requestCode == CALL_REQUEST) {
27 if (resultCode == RESULT_CANCELED) {
28 Toast.makeText(this, "CallRESULT_CANCELED", Toast.LENGTH_SHORT).show();
29 }
30 }
31 }
SendSMSActivity:
32 ((Button)findViewById(R.id.send)).setOnClickListener( new Button.OnClickListener() {
33 public void onClick(View v) {
34 SendSMSActivity.this.setResult(RESULT_OK);
35 SendSMSActivity.this.finish();
36 }
37 }):
** 注意,在setResult后,要调用finish()销毁当前的Activity,否则无法返回到原来的Activity,就无法执行原来Activity的onActivityResult函数,看到当前的Activity没反应。
RESULT_OK和RESULT_CANCELED是系统空间里面的常量,不需要自定义,直接使用就行。
另外在运行过程中,发现按Back键后,是可以返回RESULT_CANCELED的,看了SDK doc后,原来真的是那样,而且不带有数据的。这意味着,如果你设想在返回RESULT_CANCELED时并返回数据,那么需要截获Back键的事件处理,把原来返回RESULT_CANCELED的核心逻辑copy到事件处理里面。这里给个例子:
38 ((Button)findViewById(R.id.cancel)).setOnClickListener( new Button.OnClickListener() {
39 public void onClick(View v) {
40 //实例化 Bundle,设置需要传递的参数
41 Bundle bundle = new Bundle();
42 bundle.putString("phoneNO","020-123");
43
44 SendSMSActivity.this.setResult(RESULT_CANCELED,SendSMSActivity.this.getIntent().putExtras(bundle));
45 SendSMSActivity.this.finish();
46 }
47 });
48
49 @Override
50 public booleanonKeyDown(int keyCode, KeyEvent event) {
51 // 是否触发按键为back键
52 if (keyCode == KeyEvent.KEYCODE_BACK) {
53
54 //实例化 Bundle,设置需要传递的参数
55 Bundle bundle = new Bundle();
56 bundle.putString("phoneNO","020-123");
57
58 setResult(RESULT_CANCELED,this.getIntent().putExtras(bundle));
59 this.finish();
60 return true;
61 }else {
62 return super.onKeyDown(keyCode, event);
63 }
64 }
这里要注意的是,在处理Back键事件后returntrue则表示本事件不再传递给其他函数处理,可理解为由当前函数全权负责处理,所以在return前finish当前Activity,保持原来的行为表现,当然我们可以设置为隐藏当前Activity等其他行为。
Activity传送数据
在上面的代码中,我们可以看到使用Bundle来存储数据,并将其putExtras到Intent里面。Bundle使用“名字-值”来存储数据。另外注意一下,setResult需要用到Intent参数时,如何获取原来的Intent的!
Android開發筆記-Activity間互相傳值
內容說明:在頁面之間互相傳值
資料來源:Android南部工作坊
在Android的應用程式裡,會有一個Bundle的物件,它就像是用來儲存全域變數的一個地方,我們的程式在 onCreate 的時候就會看到裡面含有傳入的參數 Bundle savedInstanceState。
首先參考「轉換頁面」一文,建立新的頁面,並且將最後一段呼叫頁面的程式碼改成下面的程式,增加Bundle 參數傳遞資料,並且要求回傳值。
25 26 27 28 29 30 31 32
| Intent intent =new Intent(); intent.setClass(main.this, page2.class); //設定傳送參數 Bundle bundle =new Bundle(); bundle.putString("name1","value1"); intent.putExtras(bundle); //將參數放入intent
startActivityForResult(intent,0); //呼叫page2並要求回傳值 |
來到page2,在 onCreate 方法中,可以使用下面程式碼來取得參數:
11 12 13
| Intent intent =this.getIntent(); Bundle bundle = intent.getExtras(); //取得Bundle txt_hello.setText(bundle.getString("name1")); //輸出Bundle內容 |
如果要在page2加入回傳值,一樣使用putString加入。此時在Bundle中存在name1和name2。
1 2 3 4
| bundle.putString("name2","value2"); intent.putExtras(bundle); //將name2放入Bundle page2.this.setResult(Activity.RESULT_OK, intent); //回傳RESULT_OK page2.this.finish(); //關閉Activity |
回到main主頁面,參考讀取QR Code,增加 onActivityResult 方法,在裡面加入下面程式碼來取得回傳值:
37 38 39 40 41 42 43 44 45 46
| @Override protectedvoid onActivityResult(int requestCode, int resultCode, Intent data){ // TODO Auto-generated method stub super.onActivityResult(requestCode, resultCode, data);
if(requestCode==0&& resultCode== Activity.RESULT_OK){ Bundle bundle = data.getExtras(); txt_hello.setText(bundle.getString("name2")); } } |
***************************************************
Activity跳转与传值
一个Android应用程序很少会只有一个Activity对象,如何在多个Activity之间进行跳转,而且能够互相传值是一个很基本的要求。
在前面创建的MyApp中,我们通过点击按钮可以更新当前界面上的文本内容。现在我们想换种方式,在点击按钮后,显示一个新的屏幕,在这个屏幕上输入一段话,然后再返回到原先的界面显示刚才输入的那句话。
首先我们新建这个新屏幕的布局文件input.xml,并添加一个文本输入框和一个按钮(注意,xml元素的命名不要和其他布局文件中的定义重名,因为所有的资源都在R中进行索引,比如id,如果重名了在使用R.id.*的时候就会有问题了)。这个布局文件对应的是一个Activity,因此我们再新建一个Input类(继承自Activity)用于显示这个布局并响应事件。
然后,还有一个重要的工作,那就是在清单文件AndroidManifest.xml中告诉程序,我定义了一个新的Activity,你可以去调用它。
我们希望在以前的那个主界面上点击按钮以后可以跳转到文本输入界面,所以我们需要对按钮的onClick事件进行定义:
在这段代码里出现了一些新东西。首先是Intent,它是Android一个很重要的类.Intent直译是“意图”,什么是意图呢?比如你想从这个Activity跳转到另外一个Activity,这就是一个意图。它不但可以连接多个Activity,还可以在它们之间传递数据。在这里,我们就是用Intent从MyApp对象跳转到了Input对象。
再看紧跟着的startActivityForResult()方法,顾名思义,它可以从一个定义好的Intent对象启动一个新的Activity,并且,这个Activity会返回执行的结果,这些内容下面马上就会提到。
Activity跳转与传值
好,这里我们已经可以调出新Activity了,我们看一下执行的结果:
你马上可以想到,现在需要对新的Activity(Input)进行处理了。我们在点击“确定”按钮的时候,需要获得上面EditText对象中的文本,然后返回到前一个Activity(MyApp)中去。看我们的按钮事件处理:
这里的关键是SharedPreferences对象,这是在多个Activity(同一包中)共享数据的方式,本质上它就是一个可以在包的范围内进行数据共享的文件。
我们通过一个标签“Text”获得了和文本相关的那个SharedPreferences对象(“Text”仅仅是自己定义的一个标签),然后给它赋予一个“text”对象值为当前文本框中输入的文本。设置完成以后,设置当前Activity的执行结果为RESULT_OK,再关闭当前的Activity,剩下的事情就可以回到MyApp这个主界面中去执行了。
其实剩下的事情也很简单,在MyApp这个Activity中,我们需要重写一个函数,onActivityResult()。因为我们启动Input这个Activity的时候使用的是startActivityForResult()方法,这个方法会使Input执行完以后返回给MyApp一个结果,MyApp接收到返回结果的时候会触发onActivityResult事件,对于结果的处理就在onActivityResult()中进行。同样,我们通过“Text”这个标签获得SharedPreferences对象,再把字符串从“text”对象中取出来并显示到当前屏幕上。
另外说明一下,requestCode是用来标识请求对象,我们刚才在启动Activity的时候使用的是“startActivityForResult(intent,0)”,这里的0就是requestCode,当然,你可以设置成任何你喜欢的值。
我们看一下执行结果: