跳至主要內容

Activity之间的数据回传


Activity的数据回传

前面我们学习了怎么样把数据传递到下一个Activity,有些时间,数据是需要回传的,比如说,我们去拍照吧。

思路:点击一个按钮,然后跳转到拍照的界面,拍完以后,你是不是要显示拍到的内容呢?这个时候,就需要把数据从拍照界面传回来了吧。

Snip20171204_22.png
Snip20171204_22.png

或者大家可以想象这样一个使用场景:当你要发微信朋友圈的时候,是不是要选择拍摄或者相册选择呢?拍摄会跳转到拍摄的界面。然后拍完了再回来,回来的时候就已经显示了图片了。

其实这个过程就使用到了这种数据回传的技术了。那我们是不是要学习一下呢?

实现分析

首先,我们还是一样,要打开Activity,先创建意图对象。

  • 如果是第三方的那么就用隐式意图,自己的就用显示意图。
  • 但是不同的是,不用startActivity,而是用startActivityForResult这个方法。
  • 好,我们来看一下,这个方法要传什么参数:
Snip20171204_23.png
Snip20171204_23.png

第一个参数如大家所愿是intent。 这个方法有两个重载的方法,一个是两个参数,一个是三个参数。 那我们就把三个参数说完吧: 第二个参数是requestCode,翻译过来就是请求码,这个请求码有什么用呢?其实就是暗号! 第三个参数

 * @param options Additional options for how the Activity should be started.

这个参数的意思是设置Activity是如何启动的,在ActivityOptions这个类里面,就是封装Activity的启动参数的。这个Bundle可以理解为一个可以封装多种集合即可。

刚吃完饭回来,不知道写啥了,哈哈!!

话不多说,咱们开干吧!

举个栗子

怎么举呢?

大概是这样子的:我们从第一个界面,点击重置跳转到第二个界面,然后,充值完成以后,回到第一个界面提示!

怎么样着手呢?还是那样,是界面 的跳转,一样要创建意图对象。算了,直接看代码吧,里面已经有详细注释了,看完代码,我再把流程图画出来。

首先是第一个MainActivity的代码,它就长成这样子:

package com.sunofbeaches.activityforresultdemo;

import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
    
    private static final int sRequestCode = 1;
    
    /**
     * 充值按钮被点击,跳转到充值界面,然后进行充值。
     *
     * @param view
     */
    public void reCharge(View view) {
        Intent intent = new Intent(this, PayActivity.class);
        //如果要传输则在这之间封装,比如说有时候需要把用户的id传过去对吧。
        //一般来说,这个唯一表示会保存成全应用能访问到的变量(超时了要修改的,不能是常量)
        startActivityForResult(intent, sRequestCode);
    }
    
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        //在这里会返回充值界面返回的数据。
        if (requestCode == sRequestCode) {
            TextView resultText = (TextView) findViewById(R.id.result_text);
            //说明是我们请求的数据结果,对得上请求码
            //然后判断结果码,在支付界面 ,我们定义了-1为失败,1为成功。所以就有了:
            if (resultCode == -1) {
                //支付失败,可以是网络问题,也可以是取消充值
                resultText.setText("充值失败!如果遇到问题请联系客服!");
            } else if (requestCode == 1) {
                //充值成功,给出提示吧!
                resultText.setText("感谢您的支持!您已充值 :" + data.getStringExtra("charge") + "\n 您当前的余额是***");
            }
        }
    }
}

这个是MainActivity的UI代码:

20171207_103235.png
20171207_103235.png
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="https://schemas.android.com/apk/res/android"
    xmlns:tools="https://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:onClick="reCharge"
        android:text="充值"/>

    <TextView
        android:id="@+id/result_text"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>

</LinearLayout>

还有就是第二个Activity的代码啦,这个是支付界面 ,也就是PayActivity,要记得在Manifest里头注册一下

package com.sunofbeaches.activityforresultdemo;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;

import java.util.regex.Pattern;

/**
 * Create by TrillGates 2017/12/6
 */
public class PayActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_pay);
    }

    /**
     * 确定充值被点击了,这里提示充值成功,并且把充值的金额返回给前一个界面。
     *
     * @param view
     */
    public void confirmCharge(View view) {
        EditText chargeInput = this.findViewById(R.id.charge_input);
        //这里要对数字进行检查,对吧!
        String targetChargeText = chargeInput.getText().toString().trim();
        String reg = "/(^[1-9]([0-9]+)?(\\.[0-9]{1,2})?$)|(^(0){1}$)|(^[0-9]\\.[0-9]([0-9])?$)/";

        if (TextUtils.isEmpty(targetChargeText)) {
            //没有输入内容
            Toast.makeText(this, "您没有输入充值金额!", Toast.LENGTH_SHORT).show();
        } else {
            //如果有输入,判断是否符合金额的格式
            boolean matches = Pattern.matches(reg, targetChargeText);
            if (matches) {
                //TODO:向网络提交数据,然后充值
                //等待返回结果再更新UI
                //这里合法的话,那我们就给出提示,并且把数据设置回去即可

                //把结果封装到Intent里
                Intent resultIntent = new Intent();
                resultIntent.putExtra("charge", targetChargeText);
                setResult(1);
                finish();
            } else {
                Toast.makeText(this, "您输入的金额不合法,请重新输入!", Toast.LENGTH_SHORT).show();
            }
        }

    }

    /**
     * 取消充值
     *
     * @param view
     */
    public void cancelCharge(View view) {
        //这个是取消充值
        setResult(-1);
        finish();
    }

}

把它的布局也弄上来看一下:

20171207_103353.png
20171207_103353.png
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="https://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <EditText
        android:id="@+id/charge_input"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="请输入充值金额"
        android:inputType="number"/>

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:onClick="confirmCharge"
        android:text="确认充值"/>

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:onClick="cancelCharge"
        android:text="取消充值"/>

</LinearLayout>

这些都上完了,我们看一下这个逻辑是怎么样的:

首先,我们点击充值按钮,跳转到充值界面。

点击充值,则会检查输入内容,给出响应的动作,提示输入不合法,或者充值成功,返回结果到第一个界面。

点击取消充值,则会结束当前界面,并且返回结果给第一个界面。

代码流程:

20171207_103749.png
20171207_103749.png

跳转到这个界面:

20171207_103353.png
20171207_103353.png

点击确认充值,其实这样的检测是有问题的,这正则表达式得处理一下。因为我们已经限定的输入为数字了,也就是说小数点是没法输入的:

20171207_104445.png
20171207_104445.png

点击取消充值:

20171207_104513.png
20171207_104513.png

然后,我们都看到了setResult的内容:

这个调用以后,就会回 调到:

20171207_104553.png
20171207_104553.png

这就是整个过程啦!

要注意的事

第一,要注意过程,不是用startActivity,而是用startActivityForResult

第二,要复写onActivityResult方法,这里会有返回值

第三,第一个Activity不可finished,否则就接收不到结果了。

在视频中,我们会讲解一个例子,就是调用拍照的例子。我们写一个按钮和一个展示图片的ImageView控件,点击按钮以后,跳转到系统的拍照界面,拍完照片回来以后,获取到返回值,并且显示出来。

感谢大家的学习,接下来我们会学习新的内容。

在线视频教程

https://www.sunofbeach.net/c/1443881236287311874