今天要來聊一聊startActivityForResult也就是從Activity獲取回傳這件事

這個功能,想必如果是上過學校正規訓練課程或是補習班正規訓練課程的朋友,應該不太陌生...

好吧,也許你是忘了(´π`)

不過課題BMI計算各位是否有印象呢...恩?現在沒教?(乾我屁事XD

咳咳,ok啦,總之就是大概像這種的

->http://shung007.blogspot.com/2012/02/tqc-android-1-4-bmi-from-activity-to.html

 

那今天的重點~就是裡面的一個核心功能

就是onActivityResult啦!

那你問我onActivityResult是什麼....恩~~總之先看功能再說吧(笑)

 

 

沒有Github喔!要範例程式的留言跟我拿~

 


 

1. 什麼是onActivityResult?

 

onActivityResult是google設計的一款從另一個Activity取得回傳的API

其關係圖如下

截圖 2021-05-29 下午12.21.45

 

注意三個部分

1. startActivityForResult

2. setResult

3. onActivityResult

 

這三個部分是這整個回傳系統的核心

假設以上圖那個範例來說

startActivityForRresult跟onActivityResult是要寫在Activity1的,用以告知使用此API以及接收來自Activity2的回傳

setResult則是放在Avtivity2

 

OK看到這邊只要先有概念即可,不用求一定要完全理解

接下來我們直接上專案,然後對照著專案看就會很理解了!

 


 

2. 專案結構與介面

 

首先講一下本次專案的結構

截圖 2021-05-29 下午12.59.53

截圖 2021-05-29 下午1.01.18

 

java檔有兩個,所以介面當然也有兩個囉!(笑)

來,介面就直接給了

 

activity_main.xml

Screenshot_1622265725

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/textView_Result"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Here is result"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:id="@+id/button_FillOutForm"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Fill out question"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/textView_Result" />

</androidx.constraintlayout.widget.ConstraintLayout>

 

activity_form.xml

Screenshot_1622265730

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".FormActivity">

    <EditText
        android:id="@+id/ediTtext_Name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:ems="10"
        android:hint="請填入名字"
        android:inputType="textPersonName"
        app:layout_constraintBottom_toTopOf="@+id/editText_age"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.497"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <EditText
        android:id="@+id/editText_age"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:ems="10"
        android:hint="請填入年齡"
        android:inputType="number"
        app:layout_constraintBottom_toTopOf="@+id/guideline2"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <androidx.constraintlayout.widget.Guideline
        android:id="@+id/guideline2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        app:layout_constraintGuide_percent="0.5" />

    <androidx.constraintlayout.widget.Guideline
        android:id="@+id/guideline4"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        app:layout_constraintGuide_percent="0.5"/>

    <CheckBox
        android:id="@+id/checkBox_Student"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Is student"
        app:layout_constraintBottom_toTopOf="@+id/guideline2"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/editText_age" />

    <Button
        android:id="@+id/button_OK"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="ok"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="@+id/guideline4"
        app:layout_constraintTop_toTopOf="@+id/guideline2" />

    <Button
        android:id="@+id/button_Cancel"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:backgroundTint="@android:color/white"
        android:text="cancel"
        android:textColor="@color/purple_700"
        app:layout_constraintEnd_toStartOf="@+id/guideline4"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="@+id/guideline2" />

</androidx.constraintlayout.widget.ConstraintLayout>

 

好了,接下來就是正題了(´◑ω◐`)

 


 

3. 撰寫程式

 

3-1 設置跳轉

首先是MainActivity的部分

這部分很單純,就是建立跳轉指令,以及取得回傳

那麼,先來做跳轉指令吧

public class MainActivity extends AppCompatActivity {
    public static final int REQUEST_CODE = 1;
    public static final int RESULT_CODE = 2;
    public static final int CANCEL_CODE = 3;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button btFillOut = findViewById(R.id.button_FillOutForm);
        btFillOut.setOnClickListener(v->{
            Intent intent = new Intent(this,FormActivity.class);
            startActivityForResult(intent,REQUEST_CODE);

        });
    }
}

 

請注意,我在全域變數區域有宣告

public static final int REQUEST_CODE = 1;
public static final int RESULT_CODE = 2;
public static final int CANCEL_CODE = 3;

 

REQUEST_CODE 是用來給之後的回傳辨認是由哪個startActivityResult發出的請求指令

RESULT_CODECANCEL_CODE稍後解釋

寫到這裡若是執行,程式就會普通地進入到FormActivity的那個畫面囉~

那現在我們去FormActivity吧

 

3-2 設置回傳

 

public class FormActivity extends AppCompatActivity {
    public static final String NAME = "NAME";
    public static final String AGE = "AGE";
    public static final String STUDENT = "STUDENT";

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

        Button btOk,btCancel;
        btOk = findViewById(R.id.button_OK);
        btCancel = findViewById(R.id.button_Cancel);
        EditText edName,edAge;
        CheckBox cbIsStudent;
        edName = findViewById(R.id.ediTtext_Name);
        edAge = findViewById(R.id.editText_age);
        cbIsStudent = findViewById(R.id.checkBox_Student);


        btOk.setOnClickListener(v -> {
            getIntent().putExtra(NAME,edName.getText().toString());
            getIntent().putExtra(AGE,edAge.getText().toString());
            getIntent().putExtra(STUDENT,cbIsStudent.isChecked());

            setResult(MainActivity.RESULT_CODE,getIntent());
            finish();
        });
        btCancel.setOnClickListener(v -> {
            setResult(MainActivity.CANCEL_CODE);
            finish();
        });
    }
}

 

這裡最大的重點就是setResult的部分

setResult不是什麼我寫的副程式,這個setResult是父類別AppCompatActivity上面的繼承內容

在這個setResult內,你可以選擇用intent回傳資訊、抑或者不回傳。

但是前面的那個!!

是的,就是我剛剛說稍後說的辣個(」°ロ°)」

他就是用來設定回傳標籤的!!

 

此處還有另一個重點,就是的getIntent的部分

getIntent就是拿來包裝資料的,所以我放了兩個String跟一個boolean進去

而關於intent.putExera的操作...呃..真的不懂在留言問吧!(・ωー)~☆

 

3-2 取得回傳

 

回到MainActivity的部分

我們要來取得從剛剛的介面中拿到的資料!

首先請MainActivity複寫onActivityResult

截圖 2021-05-29 下午1.53.52

然後填入以下內容

@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
    super.onActivityResult(requestCode, resultCode, data);

    if (requestCode != REQUEST_CODE )return;

    switch (resultCode){
        case RESULT_CODE:
            TextView tvResult = findViewById(R.id.textView_Result);
            String name = data.getStringExtra(FormActivity.NAME);
            String age = data.getStringExtra(FormActivity.AGE);
            boolean isStudent = data.getBooleanExtra(FormActivity.STUDENT,false);
            tvResult.setText("名字: "+name+"\n年齡: "+age+"\n是否為學生: "+isStudent);
            break;

        case CANCEL_CODE:
            Toast.makeText(this, "取消填寫表格", Toast.LENGTH_SHORT).show();
            break;
    }
}

 

兩個重點

1. requestCode

2. resultCode

 

requestCode的意思是接收從哪個跳轉頁面的指令發出的訊息,也就是這部分

btFillOut.setOnClickListener(v->{
    Intent intent = new Intent(this,FormActivity.class);
    startActivityForResult(intent,REQUEST_CODE);

});

 

而resultCode則是接收FormActivity的setResult所設定到的Code

btOk.setOnClickListener(v -> {
    getIntent().putExtra(NAME,edName.getText().toString());
    getIntent().putExtra(AGE,edAge.getText().toString());
    getIntent().putExtra(STUDENT,cbIsStudent.isChecked());

    setResult(MainActivity.RESULT_CODE,getIntent());
    finish();
});

 

英文單字都是RE開頭....是哪個RE自己請確實注意啦!

 

最後,PO一下全部吧

 

MainActivity.java

public class MainActivity extends AppCompatActivity {
    public static final int REQUEST_CODE = 1;
    public static final int RESULT_CODE = 2;
    public static final int CANCEL_CODE = 3;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button btFillOut = findViewById(R.id.button_FillOutForm);
        btFillOut.setOnClickListener(v->{
            Intent intent = new Intent(this,FormActivity.class);
            startActivityForResult(intent,REQUEST_CODE);

        });
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        if (requestCode != REQUEST_CODE )return;

        switch (resultCode){
            case RESULT_CODE:
                TextView tvResult = findViewById(R.id.textView_Result);
                String name = data.getStringExtra(FormActivity.NAME);
                String age = data.getStringExtra(FormActivity.AGE);
                boolean isStudent = data.getBooleanExtra(FormActivity.STUDENT,false);
                tvResult.setText("名字: "+name+"\n年齡: "+age+"\n是否為學生: "+isStudent);
                break;

            case CANCEL_CODE:
                Toast.makeText(this, "取消填寫表格", Toast.LENGTH_SHORT).show();
                break;
        }
    }
}

 

 

FormActivity.java

public class FormActivity extends AppCompatActivity {
    public static final String NAME = "NAME";
    public static final String AGE = "AGE";
    public static final String STUDENT = "STUDENT";

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

        Button btOk,btCancel;
        btOk = findViewById(R.id.button_OK);
        btCancel = findViewById(R.id.button_Cancel);
        EditText edName,edAge;
        CheckBox cbIsStudent;
        edName = findViewById(R.id.ediTtext_Name);
        edAge = findViewById(R.id.editText_age);
        cbIsStudent = findViewById(R.id.checkBox_Student);


        btOk.setOnClickListener(v -> {
            getIntent().putExtra(NAME,edName.getText().toString());
            getIntent().putExtra(AGE,edAge.getText().toString());
            getIntent().putExtra(STUDENT,cbIsStudent.isChecked());

            setResult(MainActivity.RESULT_CODE,getIntent());
            finish();
        });
        btCancel.setOnClickListener(v -> {
            setResult(MainActivity.CANCEL_CODE);
            finish();
        });
    }

}

 


 

今天5/29號的台灣,正在籠罩在疫情底下

台灣各地也出現好多人性的黑暗面

老實說..寫Code時真的不該去看這些的,這其實意外地很擾亂心智..QQ

總之,天佑台灣,最好的防疫方式就是在家學習打Code~~

最後..

TK

arrow
arrow

    碼農日常 發表在 痞客邦 留言(8) 人氣()