今天要來聊一聊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
其關係圖如下
注意三個部分
1. startActivityForResult
2. setResult
3. onActivityResult
這三個部分是這整個回傳系統的核心
假設以上圖那個範例來說
startActivityForRresult跟onActivityResult是要寫在Activity1的,用以告知使用此API以及接收來自Activity2的回傳
而setResult則是放在Avtivity2內
OK看到這邊只要先有概念即可,不用求一定要完全理解
接下來我們直接上專案,然後對照著專案看就會很理解了!
2. 專案結構與介面
首先講一下本次專案的結構
java檔有兩個,所以介面當然也有兩個囉!(笑)
來,介面就直接給了
activity_main.xml
<?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
<?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_CODE跟CANCEL_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
然後填入以下內容
@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~~
最後..
留言列表