Android页面跳转和数据回传
今天我尝试用两个页面实现数据的传递和回传,出现了一些问题,把问题已经成功的案例总结如下:
具体是这样的:
有两个layout布局,两个activity。MainActivity对应的布局里有一个文本框,给文本框添加点击事件,当点击文本框时,会跳转到MoreActivity中并显示另一个布局界面,
另一个布局界面里若干条数据(使用了checkBox)用户自由选择之后,点击确定按钮,可以跳转回到MainActivity对应的界面。同时这个界面里面的文本框内容就是用
户自己选择的文本内容。
刚开始我想使用bundle实现传值,如果使用这种方式,把这一部分代码写在onCreate()里面,那么只要打开主页面方法就会被调用,可此时bundle并没有接收到来自另
一个页面传来的值,所以就会抛出异常(NullPointerException)这说明把跳转和数据接收写在同一个位置是不可行的,那么就需要把页面跳转和接收回传的数据这两个
功能分开写。
如果想在Activity中得到新打开Activity 关闭后返回的数据,需要使用系统提供的startActivityForResult(Intent intent,int requestCode)方法打开新的Activity,
新的Activity 关闭后会向前面的Activity传回数据,为了得到传回的数据,必须在前面的Activity中重写onActivityResult(int requestCode,int resultCode,Intent data)方法。
注意:startActivityForResult这个方法里会有requestCode参数,这个参数是要告诉即将跳转到的界面,跳转前的界面的“名字代号”就是requestCode,那么相应地,在跳转
到的界面如果要返回,返回的时候同样会带上一个resultCode,这个是确定这是从哪个界面跳回去的,如果只有两个页面,那这些码也就不重要了,如果要实现复杂的页
面跳转功能,就必须使用这两个参数来确定跳转唯一性。
这是系统定义的参数码的常量值:
请求码作用举例:如果A页面有两个按钮,分别实现的是不同的功能,但是点击这两个按钮都会跳转到B页面,B页面处理之后也会跳回A页面,但是B页面处理地是不同的
按钮,这时候就需要A页面的两个按钮在发出请求的时候就给两个请求带上不同的requestCode,那么B页面处理完之后也要回传不同的resultCode这样两个不同的按钮和两
组不同的数据就不会再发生冲突,在A页面重写onActivityResult(int requestCode,Intent data)方法,步骤是这样的,首先确定requestCode使用if...else语句或
者switch...case语句,然后再区分不同的resultCode,最后再接收回传的数据结果。
好了,现在上代码:
activity_main.xml
1 <EditText 2 android:id="@+id/tv_text5" 3 android:layout_width="300dp" 4 android:layout_height="154dp" 5 android:layout_above="@+id/tv_button1" 6 android:layout_alignParentEnd="true" 7 android:layout_alignParentRight 8 android:layout_marginEnd="11dp" 9 android:layout_marginRight10 android:layout_marginBottom="6dp" 11 android:hint="点击跳转填写" 12 android:onClick="onClick" 13 android:textColor="@android:color/holo_purple" />
activity_more.xml
<?xml version="1.0" encoding="utf-8"?> 2 LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height android:orientation="vertical" 6 > 7 8 TextView 9 ="@+id/tvHead" ="wrap_content" android:layout_centerHorizontal android:text="特殊情况" 14 android:layout_gravity="center" 15 ="@color/red" 16 android:background="@color/colorPrimary" 17 android:textSize="30dp" /> 18 19 android:layout_width20 21 ="@color/coral" 22 ="多选:" 23 ="23dp" 24 android:layout_marginLeft="40dp" 25 26 CheckBox 27 ="@+id/cb_0" 28 29 30 android:layout_below31 android:layout_marginTop="32dp" 32 33 android:layout_toLeftOf34 ="20dp" 35 ="无" 36 37 38 ="@+id/cb_1" 39 40 41 android:layout_alignBaseline="@+id/cb_2" 42 android:layout_alignBottom43 44 android:layout_toRightOf45 46 ="2021年2月1日至今去过或者现在居住在中高风险地区" 47 48 49 50 51 52 53 android:layout_alignLeft54 55 56 ="本人或家人正在集中隔离" 57 58 ="@+id/cb_3" 59 60 61 62 63 64 65 66 ="本人或家人有出现发热症状" 67 68 ="@+id/cb_4" 69 70 71 72 73 74 75 76 ="居住地改变" 77 78 Button 79 ="@+id/btn_add" 80 ="66dp" 81 ="38dp" 82 ="@+id/cbSing" 83 84 ="260dp" 85 ="36dp" 86 87 ="确定" 88 ="10dp" 89 </LinearLayout>
MainActivity.java
1 private TextView text5;
2 text5=findViewById(R.id.tv_text5);
3 //点击跳转事件
4 public void onClick(View view) {
5 if (view.getId() == R.id.tv_text5) {
6 Intent intent = new Intent(this,MoreActivity.class);
7 intent.putExtra("flag",RESQUEST);
8 startActivityForResult(intent,1)"> 9 }
10 }
11
12 接收复选框传过来的数据
13 @Override
14 protected void onActivityResult(int requestCode,int resultCode,@Nullable Intent data) {
15 super.onActivityResult(requestCode,resultCode,data);
16 switch (resultCode)
17 {
18 case RESULT_OK:
19 tempstr=data.getExtras().getString("mess"20 Log.v("输出“特殊情况”获取结果 ",data.getExtras().getString("mess"));
21 text5.setText(tempstr);
22 break;
23 default:
24 25 26 }
MoreActivity.java
1 package com.example.helloworld; 2 3 import android.content.Intent; 4 android.os.Bundle; 5 android.util.Log; 6 android.view.View; 7 android.widget.Button; 8 android.widget.CheckBox; 9 android.widget.CompoundButton; 10 android.widget.EditText; 11 android.widget.TextView; 12 13 androidx.annotation.Nullable; 14 androidx.appcompat.app.AppCompatActivity; 15 16 class MoreActivity extends AppCompatActivity implements View.OnClickListener { 17 CheckBox cb_0; 18 CheckBox cb_1; 19 CheckBox cb_2; 20 CheckBox cb_3; 21 CheckBox cb_4; 22 String str1="" 23 String str2="" 24 String str3="" 25 String str4="" 26 String str0="" 27 String str="" 28 29 30 onCreate(@Nullable Bundle savedInstanceState) { 31 .onCreate(savedInstanceState); 32 setContentView(R.layout.activity_more); 33 初始化多选功能的按钮 34 initMore(); 35 设置监听器 36 setListener(); 37 设置监听器 38 初始化控件对象 39 Button btn_add = findViewById(R.id.btn_add); 40 绑定点击监听器 41 btn_add.setOnClickListener(this 42 43 44 45 R.id.btn_add) { 46 Intent intent = new Intent(); 47 intent.putExtra("mess" 48 Log.v("MoreActivity得到的结果: " 49 setResult(RESULT_OK,intent); 50 .finish(); 51 52 53 CompoundButton.OnCheckedChangeListener myCheckChangelistener = CompoundButton.OnCheckedChangeListener() { 54 @Override 55 void onCheckedChanged(CompoundButton buttonView,1)">boolean isChecked) { 56 TODO Auto-generated method stub 57 设置TextView的内容显示CheckBox的选择结果 58 setText(); 59 60 }; 61 把多选框选中的东西放到主界面的text5上面, 62 并且把选中的记录放到数据库。 63 private setText() 64 { 65 66 if(cb_0.isChecked()) 67 68 str0 = cb_0.getText().toString(); 69 cb_1.setChecked(false 70 cb_2.setChecked( 71 cb_3.setChecked( 72 cb_4.setChecked( 73 Log.v("cb_0: ",str0); 74 75 else{ 76 str0="" 77 78 if(cb_0.isChecked()==) 79 80 (cb_1.isChecked()) 81 { 82 str1= cb_1.getText().toString(); 83 Log.v("cb_1: ",str1); 84 } 85 86 str1="" 87 88 (cb_2.isChecked()) 89 90 str2 = cb_2.getText().toString(); 91 Log.v("cb_2: ",str2); 92 93 94 str2="" 95 96 (cb_3.isChecked()) 97 98 str3 = cb_3.getText().toString(); 99 Log.v("cb_3: ",str3); 100 101 102 str3=""103 104 (cb_4.isChecked()) 105 106 str4 = cb_4.getText().toString(); 107 Log.v("cb_4: ",str4); 108 109 110 str4=""111 112 113 str=str0+" "+str1+" "+str2+" "+str3+" "+str4; 114 Log.v("choicesResult: "115 116 initMore(){ 117 cb_0=findViewById(R.id.cb_0); 118 cb_1=findViewById(R.id.cb_1); 119 cb_2=findViewById(R.id.cb_2); 120 cb_3=findViewById(R.id.cb_3); 121 cb_4=findViewById(R.id.cb_4); 122 123 // 124 给多选框设置监听器 125 126 setListener(){ 127 cb_0.setOnCheckedChangeListener(myCheckChangelistener); 128 cb_1.setOnCheckedChangeListener(myCheckChangelistener); 129 cb_2.setOnCheckedChangeListener(myCheckChangelistener); 130 cb_3.setOnCheckedChangeListener(myCheckChangelistener); 131 cb_4.setOnCheckedChangeListener(myCheckChangelistener); 132 133 }
在这一部分代码里,我出现了一个小问题,就是在跳转的时候会有一个finish()函数的调用,如果调用不当就会出现闪退的情况。
finish()
用于结束一个Activity的生命周期
问题是这样的:假如从A跳转到B,那么A里面是不可以写这个方法的,因为一个页面不可以既跳转,又结束自身声明周期。B页面里需要回跳的时候要写这个方法。
不使用finish():从activity 1中启动activity 2,然后在activity 2 启动activity 3, 这时按下返回键 程序就返回到了activity 2,再按下返回键 就返回到activity 1;
使用finish():从activity 1中启动activity 2,在activity 2调用finish(),然后在activity 2 启动activity 3,这时按下返回键 程序就直接返回了activity 1
注意:
如果在startActivityForResult起来的Activity里面设置setResult,
结果并不会马上返回给parent的Activity,只有当前Activity被finish,
结果才会被发送给parent的onActivityResult去处理!
那么也就是说,被跳转的页面必须写finish()方法,数据才可以完成回传。
activity返回result是在被finish的时候,也就是说调用setResult()方法必须在finish()之前。
那么如果在如下方法中调用setResult()也有可能不会返回成功:
onPause(), onStop(), onDestroy(),
因为这些方法调用不一定是在finish之前的。
Tomorrow the birds will sing.