Codelab Intent dengan ResultActivity
Pada modul ini kita akan membedah hubungan activity dan intent dalam menerima nilai balik. Kadang kala ketika kita menjalankan sebuah activity dari activity lain, kita mengharapkan ada nilai hasil balik dari activity yang dijalankan ketika ia ditutup.
Contohnya kita memiliki activity A yang menjalankan activity B untuk melakukan sebuah proses. Lalu nilai hasil dari proses tersebut dikirimkan kembali ke activity A sebelum activity B ditutup dengan pemanggilan metode finish().
Itulah yang dinamakan sebuah activity menerima nilai hasil balik dari activity yang dia jalankan. Supaya lebih jelas, ayo kita lanjutkan lagi proses ngoding-nya.
- Sekarang untuk menerapkan konsep di atas, buat sebuah activity baru dengan nama MoveForResultActivity.
- Setelah itu pada activity_move_for_result.xml silakan kondisikan layout kita dengan 1 buah textview, 1 buah radiogroup, 3 buah radiobutton dan 2 buah button sebagai berikut:
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical"
- android:padding="16dp">
- <TextView
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginBottom="16dp"
- android:text="@string/choose_number" />
- <RadioGroup
- android:id="@+id/rg_number"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="vertical">
- <RadioButton
- android:id="@+id/rb_50"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginBottom="16dp"
- android:text="@string/_50" />
- <RadioButton
- android:id="@+id/rb_100"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginBottom="16dp"
- android:text="@string/_100" />
- <RadioButton
- android:id="@+id/rb_150"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginBottom="16dp"
- android:text="@string/_150" />
- <RadioButton
- android:id="@+id/rb_200"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginBottom="16dp"
- android:text="@string/_200" />
- </RadioGroup>
- <Button
- android:id="@+id/btn_choose"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:text="@string/choose" />
- </LinearLayout>
- Tampilannya adalah seperti ini:
- Setelah selesai, lanjutkan ke berkas MoveForResultActivity dengan mengenalkan komponen yang sudah ditambahkan
- private lateinit var btnChoose: Button
- private lateinit var rgNumber: RadioGroup
- companion object {
- const val EXTRA_SELECTED_VALUE = "extra_selected_value"
- const val RESULT_CODE = 110
- }
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
- setContentView(R.layout.activity_move_for_result)
- btnChoose = findViewById(R.id.btn_choose)
- rgNumber = findViewById(R.id.rg_number)
- }
- public class MoveForResultActivity extends AppCompatActivity {
- private Button btnChoose;
- private RadioGroup rgNumber;
- public static final String EXTRA_SELECTED_VALUE = "extra_selected_value";
- public static final int RESULT_CODE = 110;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_move_for_result);
- btnChoose = findViewById(R.id.btn_choose);
- rgNumber = findViewById(R.id.rg_number);
- }
- }
Kemudian kita beri aksi pada button dengan menuliskan kode sebagai berikut
- class MoveForResultActivity : AppCompatActivity(), View.OnClickListener {
- ...
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
- setContentView(R.layout.activity_move_for_result)
- btnChoose = findViewById(R.id.btn_choose)
- rgNumber = findViewById(R.id.rg_number)
- btn_choose.setOnClickListener(this)
- }
- override fun onClick(v: View) {
- if (v.id == R.id.btn_choose) {
- if (rg_number.checkedRadioButtonId != 0) {
- var value = 0
- when (rg_number.checkedRadioButtonId) {
- R.id.rb_50 -> value = 50
- R.id.rb_100 -> value = 100
- R.id.rb_150 -> value = 150
- R.id.rb_200 -> value = 200
- }
- val resultIntent = Intent()
- resultIntent.putExtra(EXTRA_SELECTED_VALUE, value)
- setResult(RESULT_CODE, resultIntent)
- finish()
- }
- }
- }
- }
- public class MoveForResultActivity extends AppCompatActivity implements View.OnClickListener {
- ...
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_move_for_result);
- ...
- btnChoose.setOnClickListener(this);
- }
- @Override
- public void onClick(View v) {
- if (v.getId() == R.id.btn_choose) {
- if (rgNumber.getCheckedRadioButtonId() != 0) {
- int value = 0;
- switch (rgNumber.getCheckedRadioButtonId()) {
- case R.id.rb_50:
- value = 50;
- break;
- case R.id.rb_100:
- value = 100;
- break;
- case R.id.rb_150:
- value = 150;
- break;
- case R.id.rb_200:
- value = 200;
- break;
- }
- Intent resultIntent = new Intent();
- resultIntent.putExtra(EXTRA_SELECTED_VALUE, value);
- setResult(RESULT_CODE, resultIntent);
- finish();
- }
- }
- }
- }
Pada activity_main tambahkan lagi satu button dan satu textview yang akan kita gunakan untuk menjalankan MoveForResultActivity sebagai berikut:
- <Button
- android:id="@+id/btn_move_for_result"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginBottom="16dp"
- android:text="@string/move_with_result" />
- <TextView
- android:id="@+id/tv_result"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:gravity="center"
- android:text="@string/result_from_activity"
- android:textSize="24sp" />
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical"
- android:padding="16dp">
- <Button
- android:id="@+id/btn_move_activity"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginBottom="16dp"
- android:text="@string/move_activity" />
- <Button
- android:id="@+id/btn_move_activity_data"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginBottom="16dp"
- android:text="@string/move_with_data" />
- <Button
- android:id="@+id/btn_move_activity_object"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginBottom="16dp"
- android:text="@string/move_with_object" />
- <Button
- android:id="@+id/btn_dial_number"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginBottom="16dp"
- android:text="@string/dial_number" />
- <Button
- android:id="@+id/btn_move_for_result"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginBottom="16dp"
- android:text="@string/move_with_result" />
- <TextView
- android:id="@+id/tv_result"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:gravity="center"
- android:text="@string/result_from_activity"
- android:textSize="24sp" />
- </LinearLayout>
Setelah selesai, kita lanjut mengenalkan textview dan button ke dalam berkas MainActivity
- class MainActivity : AppCompatActivity(), View.OnClickListener {
- private lateinit var tvResult: TextView
- companion object {
- private const val REQUEST_CODE = 100
- }
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
- setContentView(R.layout.activity_main)
- ...
- val btnMoveForResult:Button = findViewById(R.id.btn_move_for_result)
- btnMoveForResult.setOnClickListener(this)
- tvResult = findViewById(R.id.tv_result);
- }
- }
- public class MainActivity extends AppCompatActivity implements View.OnClickListener{
- TextView tvResult;
- private int REQUEST_CODE = 100;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- ...
- Button btnMoveForResult = findViewById(R.id.btn_move_for_result);
- btnMoveForResult.setOnClickListener(this);
- tvResult = findViewById(R.id.tv_result);
- }
- ...
- }
Selanjutnya kita beri aksi pada button dengan menyesuaikan kodenya sebagai berikut
- ...
- override fun onClick(v: View) {
- when (v.id) {
- ...
- R.id.btn_move_for_result -> {
- val moveForResultIntent = Intent(this@MainActivity, MoveForResultActivity::class.java)
- startActivityForResult(moveForResultIntent, REQUEST_CODE)
- }
- }
- }
- override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
- super.onActivityResult(requestCode, resultCode, data)
- if (requestCode == REQUEST_CODE) {
- if (resultCode == MoveForResultActivity.RESULT_CODE) {
- val selectedValue = data?.getIntExtra(MoveForResultActivity.EXTRA_SELECTED_VALUE, 0)
- tv_result.text = "Hasil : $selectedValue"
- }
- }
- }
- ...
- @Override
- public void onClick(View v) {
- switch (v.getId()) {
- ...
- case R.id.btn_move_for_result:
- Intent moveForResultIntent = new Intent(MainActivity.this, MoveForResultActivity.class);
- startActivityForResult(moveForResultIntent, REQUEST_CODE);
- break;
- }
- }
- @Override
- protected void onActivityResult(int requestCode, int resultCode, Intent data) {
- super.onActivityResult(requestCode, resultCode, data);
- if (requestCode == REQUEST_CODE) {
- if (resultCode == MoveForResultActivity.RESULT_CODE) {
- int selectedValue = data.getIntExtra(MoveForResultActivity.EXTRA_SELECTED_VALUE, 0);
- tvResult.setText(String.format("Hasil : %s", selectedValue));
- }
- }
- }
- Setelah selesai, pastikan tidak ada bagian kode yang tertinggal. Jalankan kembali aplikasinya, dan coba Anda pilih tombol Pindah Activity untuk Result. Pilih angka yang Anda suka dan lihat hasilnya. Di MainActivity sudah ada angka yang tadi Anda pilih di obyek textview.
Bedah Kode
startActivity dan startActivityForResult
Perbedaan mendasar antara perpindahan activity untuk menghasilkan nilai balik dengan tidak, adalah pada metode untuk menjalankan obyek intent-nya. Sebelumnya kita menggunakan startActivity(Intent) untuk berpindah activity. Nah, kali ini kita menggunakan startActivityForResult(Intent, RequestCode).
- val moveForResultIntent = Intent(this@MainActivity, MoveForResultActivity::class.java)
- startActivityForResult(moveForResultIntent, REQUEST_CODE)
- Intent moveForResultIntent = new Intent(MainActivity.this, MoveForResultActivity.class);
- startActivityForResult(moveForResultIntent, REQUEST_CODE);
Pada baris di atas, kita akan menjalankan sebuah activity melalui intent untuk nilai balik ke activity yang menjalankan di mana nilai REQUEST_CODE adalah 110. Penentuan nilai 110 itu dibebaskan dan kalau bisa disesuaikan dengan kebutuhan pengembangan aplikasi.
Result Activity
Kemudian pada MoveForResultActivity kita memilih satu angka yang kita suka, sebagai contoh angka 150. Kemudian tekanlah tombol ‘Pilih’. Maka baris kode di bawah ini akan dijalankan.
- override fun onClick(v: View) {
- if (v.id == R.id.btn_choose) {
- if (rg_number.checkedRadioButtonId != 0) {
- var value = 0
- when (rg_number.checkedRadioButtonId) {
- R.id.rb_50 -> value = 50
- R.id.rb_100 -> value = 100
- R.id.rb_150 -> value = 150
- R.id.rb_200 -> value = 200
- }
- val resultIntent = Intent()
- resultIntent.putExtra(EXTRA_SELECTED_VALUE, value)
- setResult(RESULT_CODE, resultIntent)
- finish()
- }
- }
- }
- @Override
- public void onClick(View v) {
- if (v.getId() == R.id.btn_choose){
- if (rgNumber.getCheckedRadioButtonId() != 0){
- int value = 0;
- switch (rgNumber.getCheckedRadioButtonId()){
- case R.id.rb_50:
- value = 50;
- break;
- case R.id.rb_100:
- value = 100;
- break;
- case R.id.rb_150:
- value = 150;
- break;
- case R.id.rb_200:
- value = 200;
- break;
- }
- Intent resultIntent = new Intent();
- resultIntent.putExtra(EXTRA_SELECTED_VALUE, value);
- setResult(RESULT_CODE, resultIntent);
- finish();
- }
- }
- }
Pada kode di atas berfungsi untuk melakukan validasi nilai dari obyek radiobutton yang dipilih. Bila ada nilai dari radiobutton, maka proses selanjutnya adalah menentukan obyek radiobutton mana yang diklik berdasarkan nilai dari rgNumber.getCheckedRadioButtonId().
Mengapa kita tidak memeriksa langsung ke obyek radiobutton? Karena kita menggunakan radiogroup sebagai parent pada obyek-obyek radiobutton. Secara otomatis kita bisa mendapatkan mana obyek radiobutton yang dipilih dengan rgNumber.getCheckedRadioButtonId().
- <RadioGroup
- android:id="@+id/rg_number"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="vertical">
- <RadioButton
- android:id="@+id/rb_50"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:text="50"
- android:layout_marginBottom="16dp"/>
- <RadioButton
- android:id="@+id/rb_100"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:text="100"
- android:layout_marginBottom="16dp"/>
- <RadioButton
- android:id="@+id/rb_150"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:text="150"
- android:layout_marginBottom="16dp"/>
- <RadioButton
- android:id="@+id/rb_200"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:text="200"
- android:layout_marginBottom="16dp"/>
- </RadioGroup>
Selanjutnya, ketika sudah didapatkan nilainya, maka baris ini akan dieksekusi:
- val resultIntent = Intent()
- resultIntent.putExtra(EXTRA_SELECTED_VALUE, value)
- setResult(RESULT_CODE, resultIntent)
- finish()
- Intent resultIntent = new Intent();
- resultIntent.putExtra(EXTRA_SELECTED_VALUE, value);
- setResult(RESULT_CODE, resultIntent);
- finish();
Kita membuat sebuah intent tanpa ada inputan apapun di konstruktornya. Kemudian kita meletakkan variabel value ke dalam metode putExtra(Key, Value) dengan EXTRA_SELECTED_VALUE bertipekan static string dan bernilai “extra_selected_value”. Kemudian kita jadikan obyek resultIntent yang telah dibuat sebelumnya menjadi parameter dari setResult(RESULT_CODE, Intent).
Setelah itu, kita panggil method finish() untuk menutup MoveForResultActivity.
Setelah itu, kita panggil method finish() untuk menutup MoveForResultActivity.
Ketika MoveForResultActivity telah tertutup sempurna, maka metode onActivityResult() pada MainActivity akan dijalankan.
- override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
- super.onActivityResult(requestCode, resultCode, data)
- if (requestCode == REQUEST_CODE) {
- if (resultCode == MoveForResultActivity.RESULT_CODE) {
- val selectedValue = data?.getIntExtra(MoveForResultActivity.EXTRA_SELECTED_VALUE, 0)
- tv_result.text = "Hasil : $selectedValue"
- }
- }
- }
- @Override
- protected void onActivityResult(int requestCode, int resultCode, Intent data) {
- super.onActivityResult(requestCode, resultCode, data);
- if (requestCode == REQUEST_CODE){
- if (resultCode == MoveForResultActivity.RESULT_CODE){
- int selectedValue = data.getIntExtra(MoveForResultActivity.EXTRA_SELECTED_VALUE, 0);
- tvResult.setText("Hasil : "+selectedValue);
- }
- }
- }
Di sinilah MainActivity akan merespon terhadap nilai balik yang dikirimkan oleh MoveForResultActivity. Pada baris 4 di atas, dilakukan perbandingan apakah requestCode sama dengan yang dikirimkan oleh MainActivity.
Kemudian pada baris 5, periksa apakah nilai resultCode sama yang dikirim oleh MoveForResultActivity. Bila iya, maka data radiobutton yang dipilih akan ditampilkan di textview tvResult.
Kombinasi antara requestCode dan resultCode akan sangat berguna ketika kita ingin membuat suatu activity yang dapat merespon banyak skenario. Perhatikan contoh kode di bawah ini, di mana terjadi banyak skenario yang bisa terjadi.
- override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
- super.onActivityResult(requestCode, resultCode, data)
- if (requestCode == REQUEST_1) {
- if (resultCode == RESULT_YES) {
- } else if (resultCode == RESULT_NO) {
- }
- } else if (requestCode == REQUEST_2) {
- if (resultCode == Activity.RESULT_OK) {
- } else if (resultCode == Activity.RESULT_CANCELED) {
- } else {
- // do nothing
- }
- } else {
- // do something
- }
- }
- protected void onActivityResult(int requestCode, int resultCode, Intent data) {
- super.onActivityResult(requestCode, resultCode, data);
- if (requestCode == REQUEST_1) {
- if (resultCode == RESULT_YES) {
- } else if (resultCode == RESULT_NO) {
- }
- } else if (requestCode == REQUEST_2) {
- if (resultCode == RESULT_OK) {
- } else if (resultCode == RESULT_CANCELED) {
- } else {
- // do nothing
- }
- } else {
- // do something
- }
- }
Pada realita sehari-hari, konsep yang sudah kita pelajari akan bersinggungan dengan aplikasi native lainnya. Misalnya, jika aplikasi kita membutuhkan gambar yang diambil dari kamera atau gallery photo. Tentu kita mengharapkan nilai balik berupa alamat foto yang dapat diterima oleh activity yang menjalankan. Begitu juga jika kita membutuhkan data kontak yang berasal dari aplikasi phonebook bawaan peranti Android.
Untuk lebih dalam lagi silakan pelajari materi pada tautan berikut:
Keren! Anda sudah belajar dasar-dasar penggunaan intent secara umum di proyek aplikasi Android. 4 intent secara eksplisit dan 1 secara implisit dengan satu di antaranya mencakup nilai balik dari activity yang dijalankan.
Untuk mendalami materi intent, silakan meluncur ke tautan di bawah ini.
Untuk source code materi, silakan unduh di tautan berikut ini :