今天的比較想聊一下關於RegisterForActivityResult()這部分

其實RegisterForActivityResult()這個的原型是startActivityForResult, 也就是在Android開發中最經典的兩個Activity之間互相回傳資料的一個函式庫(・ω・)b

不過這個startActivityForResult的函式庫在這個文件中,Google官方表示「強烈建議」使用今天所要介紹的這個方法

那麼,究竟改了哪裡呢?接下來這篇文章將會與之前寫過的這篇文章

-> 碼農日常-『Android studio』啟動Activity並獲取返回的結果-onActivityResult

作比較,基本上介面跟程式碼內容都會盡可能與之相同,僅在有更動的地方做最小幅度的更動,方便你對於兩個方法做比較

那麼,開始吧!首先送上動圖

還有Github

點我

好的,那開始吧!


 

1. 專案結構與介面

 

原則上,本次的介面為了與上邊文章做比較,因此介面與結構完全一致

在這邊就直接給Code,不多廢言|・ω・)

 

結構

截圖 2021-05-29 下午12.59.53

截圖 2021-05-29 下午1.01.18

 

activity_main.xml

Screenshot_20221230_163259

<?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_20221230_164313

 

<?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>

 


2. 撰寫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);
//            startActivity(intent); 單純跳轉
            resultLauncher.launch(intent); //需要註冊的跳轉
        });

    }


    ActivityResultLauncher<Intent> resultLauncher = registerForActivityResult(
            new ActivityResultContracts.StartActivityForResult(),
//              ✭✭不採用正規表達式可以這樣寫✭✭
//            new ActivityResultCallback<ActivityResult>() {
//                @Override
//                public void onActivityResult(ActivityResult result) {
//
//                }
//            }
            result ->{
                if (result.getResultCode() == RESULT_CANCELED||
                        result.getResultCode() == CANCEL_CODE)
                    Toast.makeText(this, "取消填寫表格", Toast.LENGTH_SHORT).show();
                else if(result.getResultCode() == RESULT_CODE){
                    TextView tvResult = findViewById(R.id.textView_Result);
                    String name = result.getData().getStringExtra(FormActivity.NAME);
                    String age = result.getData().getStringExtra(FormActivity.AGE);
                    boolean isStudent = result.getData().getBooleanExtra(FormActivity.STUDENT,false);
                    tvResult.setText("名字: "+name+"\n年齡: "+age+"\n是否為學生: "+isStudent);
                }
            }
    );

}

 

注意Code之中的粉底白字部分,這個部分就是與先前不同的部分

在舊的函式庫中,這裡的程式要寫入startActivityForResult()這個方法

不過在這裡,我們改成了resultLauncher.launch();

有一點要特別注意的是,當我們加入resultLauncher.launch();的時候,相當於是把startActivity()跳轉的功能也一起寫了

因此如果有呼叫此函式庫的話,注意不要與混用喔!

 

最後在下半部記得要加入ActivityResultLauncher來接收回傳的訊息

就完成這部分的實作囉!

ActivityResultLauncher<Intent> resultLauncher = registerForActivityResult(
        new ActivityResultContracts.StartActivityForResult(),
        new ActivityResultCallback<ActivityResult>() {
            @Override
            public void onActivityResult(ActivityResult result) {
                
            }
        }
);

P.s 忘記要輸入什麼時,可以直接複製這邊↑

 

再來是取得資訊的部分,取得資訊的過程基本上跟舊版中的onActivityResult大同小異

舊版中,取得訊息代號與取得資料的函式庫是被寫成分開的,如下

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

而在新版中,這些東西原則上都是被寫在一個result內的,如下綠底白字橘底白字的部分

result ->{
    if (result.getResultCode() == RESULT_CANCELED||
            result.getResultCode() == CANCEL_CODE)
        Toast.makeText(this, "取消填寫表格", Toast.LENGTH_SHORT).show();
    else if(result.getResultCode() == RESULT_CODE){
        TextView tvResult = findViewById(R.id.textView_Result);
        String name = result.getData().getStringExtra(FormActivity.NAME);
        String age = result.getData().getStringExtra(FormActivity.AGE);
        boolean isStudent = result.getData().getBooleanExtra(FormActivity.STUDENT,false);
        tvResult.setText("名字: "+name+"\n年齡: "+age+"\n是否為學生: "+isStudent);
    }
}

 

以上就是更動的部分,在撰寫的時候需要特別注意囉!

 


 

3. 撰寫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();
        });
    }
}

 

雖然古人有云「不出意外的話就要出意外了」(並沒有

但原則上程式都有打對的話是不會出意外的,請儘管放心執行吧!

 


 

2022/12/30寫的這篇,我正好完成在日本為期9個月的語言學校留學

現在的這個時間點剛好是日本放假,而我正在家裡等待放完假上工....

目前來說,我明年開始會在東京開始成為歪果仁打工大軍的一員

每天默默耕耘那點點程式碼

雖然不出意外的話就總是會出意外

但我的人生已經很多意外了,應該不差那點點意外吧(笑)

總之,提前祝大家新年快樂,接下來本站應該會繼續開始連載

請再次多多指教!

TK

arrow
arrow
    創作者介紹
    創作者 碼農日常 的頭像
    碼農日常

    碼農日常大小事

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