Activity
Seperti ketika Anda membuat project baru di Android Studio, biasanya akan ada dua berkas yang sudah tercipta, yaitu MainActivity dan activity_main.xml.
Umumnya dalam sebuah aplikasi terdapat lebih dari satu activity yang saling terhubung dengan tugas yang berbeda-beda. Yang perlu diperhatikan yaitu setiap Activity harus terdaftar di AndroidManifest.xml.
Activity Lifecycle

Pemahaman yang baik tentang daur hidup activity akan membuat implementasi rancangan aplikasi Anda menjadi lebih baik. Hal ini juga akan meminimalisir terjadinya error/bug/force close yang tidak diinginkan.
Last In, First Out (LIFO)
|
Gambar 1
|
Gambar 2
|
Gambar 3
|
|
Aktif: Activity 1
onCreate() → onStart() → onResume()
|
Aktif: Activity 2
Stack append: Activity 2 [ onResume() ]
|
Activity 1
onStop() → onRestart() → onStart() → onResume()
|
|
Aksi: Klik Button1 (Pindah)
|
Aksi: Klik Hardware Back Button
|
Aktif: Activity 1
|
|
Stack append: Activity 1 [ onStop() ]
|
Activity 2 [ finish() ]
Stack pop: Activity 2 [ onDestroy() ]
|
- Gambar 1
Jika Anda memiliki sebuah aplikasi yang terdiri dari 2 activity, maka activity pertama akan dijalankan setelah pengguna meluncurkan aplikasi melalui ikon aplikasi di layar device. Activity yang ada saat ini berada pada posisi activity running setelah melalui beberapa state onCreate (created) → onStart (started) → onResume (resumed) dan masuk ke dalam sebuah stack activity.
Bila pada activity pertama Anda menekan sebuah tombol untuk menjalankan activity kedua, maka posisi state dari activity pertama berada pada posisi stop. Saat itu, callback onStop() pada activity pertama akan dipanggil.
Ini terjadi karena activity pertama sudah tidak berada pada layar foreground / tidak lagi ditampilkan. Semua informasi terakhir pada activity pertama akan disimpan secara otomatis.
Sementara itu, activity kedua masuk ke dalam stack dan menjadi activity terakhir yang masuk. - Gambar 2
Activity kedua sudah muncul di layar sekarang. Ketika Anda menekan tombol back pada physical button menu utama atau menjalankan metode finish(), maka activity kedua Anda akan dikeluarkan dari stack.
Pada kondisi di atas, state activity kedua akan berada pada destroy. Oleh karenanya, metode onDestroy() akan dipanggil.
Kejadian keluar dan masuk stack pada proses di atas menandakan sebuah model Last In, First Out. Activity kedua menjadi yang terakhir masuk stack (Last In) dan yang paling pertama keluar dari stack (First Out). - Gambar 3Activity Pertama akan dimunculkan kembali di layar setelah melalui beberapa state dengan rangkaian callback method yang terpanggil, onStop → onRestart → onStart → onResume.
Saving Activity State

Tujuan
Logika Dasar
Codelab Membuat Proyek Baru
-
Buat proyek baru dengan klik File → New → New Project pada Android Studio Anda atau Anda bisa memilih Start a new Android Studio project di bagian dashboard.
- Pada bagian ini kita akan memilih tipe activity awal dari template yang telah disediakan. Saat ini Android Studio sudah menyediakan berbagai macam template activity dari yang paling sederhana hingga yang paling kompleks seperti:
Jenis-jenis template Activity Fungsinya Add No Activity Tidak ada activity yang ditambahkan Basic Activity Activity dengan template komponen material design seperti FloatingActionButton Bottom Navigation Activity Activity dengan tampilan side bar menu di bagian bawah Empty Activity Activity dalam bentuk yang paling dasar Fragment + ViewModel Activity dengan menerapkan architecture component Fullscreen Activity Activity fullscreen tanpa status bar Google AdMob Ads Activity Activity dengan konfigurasi default iklan Admob Google Maps Activity Activity dengan menyediakan konfigurasi dasar Google Maps Login Activity Activity untuk halaman login Master / Detail Flow Activity yang diperuntukan untuk alur aplikasi master detail pada peranti tablet Navigation Drawer Activity Activity dengan tampilan side bar menu Scrolling Activity Activity dengan kemampuan scroll konten didalamnya secara vertikal Settings Activity Activity yang diperuntukan untuk konfigurasi aplikasi Tabbed Activity Activity yang diperuntukan untuk menampilkan lebih dari satu tampilan, dapat digeser ke kanan dan ke kiri (swipe) dengan menggunakan komponen ViewPager Selain itu, Anda juga bisa memilih target device mana yang akan Anda buat seperti Phone and Tablet, Wear OS, TV, Android Auto atau Android Things.
Saat ini kita pilih tipe Empty Activity, klik Next untuk melanjutkan.
- Selanjutnya masukkan nama aplikasi dan nama package aplikasi Anda. Sebaiknya jangan sama dengan apa yang ada di contoh, karena ini berfungsi sebagai id dari aplikasi yang Anda buat. Kemudian Anda bisa menentukan lokasi proyek yang akan Anda buat. Setelah itu pilih tipe gawai/peranti (device) untuk aplikasi beserta target minimum SDK yang akan digunakan. Pilihan target Android SDK akan mempengaruhi banyaknya peranti yang dapat menggunakan aplikasi. Di sini kita memilih nilai minimum SDK kita pasang ke Level 21 (Lollipop). Klik Finish untuk melanjutkan.
Catatan: Untuk Android Studio versi 3.4.1 ke bawah, penggunaan AndroidX belum menjadi default. Jadi, silakan beri tanda centang pada Use AndroidX artifacts di setiap kali membuat project. Informasi lebih detail mengenai AndroidX bisa Anda lihat di sini, dan untuk melihat perubahan antara sebelum dan sesudah AndroidX atau cara migrasi menggunakan AndroidX bisa lihat di sini. Perlu Anda ketahui juga, ketika Anda sudah menggunakan AndroidX maka Anda tidak bisa menambahkan library lama atau sebelum AndroidX. Kelas ini menggunakan bahasa Kotlin sebagai bahasa utama. Namun jika anda ingin menggunakan bahasa Java, ubahlah languages dari Kotlin menjadi Java. Jangan khawatir, di dalam tutorial ini kalian bisa melihat kode dalam bahasa Kotlin dan Java secara berdampingan.
- Tampilan layar Anda akan seperti contoh di bawah ini:
- Di sebelah kanan Anda adalah workspace di mana Activity anda berada dan bernama MainActivity dengan layout-nya activity_main.xml. Di sebelah kiri Anda terdapat struktur proyek, di mana nanti kita akan banyak menambahkan berbagai komponen baru, asset, dan library. Untuk lebih mengenal Android Studio lebih dalam silakan baca materi di sini.
- Ngoding Layout untuk user interface aplikasi
- Ngoding Activity untuk menambahkan logika aplikasi
Codelab Layouting
Menambahkan Code Sederhana pada Layout Activity
- Silakan pilih tab berkas activity_main.xml pada workspace Anda(res/layout/activity_main.xml).
Pastikan project window pada pilihan Android, seperti di bawah ini:
Maka akan ada tampilan seperti ini, kemudian pilih tab Code di sebelah pojok kanan atas.
Dan tambahkan baris-baris 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:padding=“16dp”
- android:orientation=“vertical”>
- <TextView
- android:layout_width=“match_parent”
- android:layout_height=“wrap_content”
- android:text=“Panjang” />
- <EditText
- android:id=“@+id/edt_length”
- android:layout_width=“match_parent”
- android:layout_height=“wrap_content”
- android:inputType=“numberDecimal”
- android:lines=“1” />
- <TextView
- android:layout_width=“match_parent”
- android:layout_height=“wrap_content”
- android:text=“Lebar” />
- <EditText
- android:id=“@+id/edt_width”
- android:layout_width=“match_parent”
- android:layout_height=“wrap_content”
- android:inputType=“numberDecimal”
- android:lines=“1” />
- <TextView
- android:layout_width=“match_parent”
- android:layout_height=“wrap_content”
- android:text=“Tinggi” />
- <EditText
- android:id=“@+id/edt_height”
- android:layout_width=“match_parent”
- android:layout_height=“wrap_content”
- android:inputType=“numberDecimal”
- android:lines=“1” />
- <Button
- android:id=“@+id/btn_calculate”
- android:layout_width=“match_parent”
- android:layout_height=“wrap_content”
- android:text=“Hitung” />
- <TextView
- android:id=“@+id/tv_result”
- android:layout_width=“match_parent”
- android:layout_height=“wrap_content”
- android:gravity=“center”
- android:text=“Hasil”
- android:textSize=“24sp”
- android:textStyle=“bold” />
- Perlu diperhatikan root layout (tag layout terluar) yang dipakai di sini adalah LinearLayout. Jika kita menggunakan Android Studio versi 3 ke atas maka secara default root yang dipakai adalah ConstraintLayout. Agar sesuai dengan latihan ini, kita tinggal menggantinya menjadi LinearLayout. Untuk materi tentang Layout akan dibahas nanti pada modul yang berbeda.
- Kemudian akan muncul warning pada atribut android:text pada layout tersebut.
Ini karena kita melakukan hardcoding pada nilai string-nya. Mari kita hilangkan code warning tersebut dengan menekan Alt+Enter (option + return pada Mac) atau menekan lampu kuning yang muncul pada attribute android:text.
Akan muncul dialog seperti ini, pilih extract string resource. -
Kemudian akan muncul dialog seperti di bawah ini. Sesuaikan dengan nama yang ada.
-
Fungsi extract string resource akan secara otomatis menambahkan nilai dari android:text ke dalam berkas res → values → strings.xml.
Lakukan hal yang sama pada komponen view lainnya hingga tidak ada warning lagi. Jika kita buka berkas strings.xml, maka isinya akan menjadi seperti ini:
- <string name="app_name">BarVolume
- <string name="width">Lebar
- <string name="height">Tinggi
- <string name="calculate">Hitung
- <string name="result">Hasil
- <string name="length">Panjang
-
Maka kode di dalam activity_main.xml akan menjadi seperti ini:
- <?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:padding=“16dp”
- android:orientation=“vertical”>
- <TextView
- android:layout_width=“match_parent”
- android:layout_height=“wrap_content”
- android:text=“@string/length” />
- <EditText
- android:id=“@+id/edt_length”
- android:layout_width=“match_parent”
- android:layout_height=“wrap_content”
- android:inputType=“numberDecimal”
- android:lines=“1” />
- <TextView
- android:layout_width=“match_parent”
- android:layout_height=“wrap_content”
- android:text=“@string/width” />
- <EditText
- android:id=“@+id/edt_width”
- android:layout_width=“match_parent”
- android:layout_height=“wrap_content”
- android:inputType=“numberDecimal”
- android:lines=“1” />
- <TextView
- android:layout_width=“match_parent”
- android:layout_height=“wrap_content”
- android:text=“@string/height” />
- <EditText
- android:id=“@+id/edt_height”
- android:layout_width=“match_parent”
- android:layout_height=“wrap_content”
- android:inputType=“numberDecimal”
- android:lines=“1” />
- <Button
- android:id=“@+id/btn_calculate”
- android:layout_width=“match_parent”
- android:layout_height=“wrap_content”
- android:text=“@string/calculate” />
- <TextView
- android:id=“@+id/tv_result”
- android:layout_width=“match_parent”
- android:layout_height=“wrap_content”
- android:gravity=“center”
- android:text=“@string/result”
- android:textSize=“24sp”
- android:textStyle=“bold” />
-
Jika Anda perhatikan, hasil layout sementara akan menjadi seperti ini:
Selain menggunakan Teks seperti di atas, Anda juga dapat membuat layout dengan menggunakan design. Untuk tutorialnya dapat Anda lihat divideo berikut:
Codelab Kode Logika
Menambahkan Kode Logika Sederhana pada MainActivity.
- Selanjutnya setelah selesai, lanjutkan dengan membuka berkas MainActivity dan lanjutkan ngoding baris-baris di bawah ini.
Tambahkan beberapa variabel yang akan digunakan untuk menampung view.
- private lateinit var edtWidth: EditText
- private lateinit var edtHeight: EditText
- private lateinit var edtLength: EditText
- private lateinit var btnCalculate: Button
- private lateinit var tvResult: TextView
- private EditText edtWidth;
- private EditText edtHeight;
- private EditText edtLength;
- private Button btnCalculate;
- private TextView tvResult;
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
- setContentView(R.layout.activity_main)
- edtWidth = findViewById(R.id.edt_width)
- edtHeight = findViewById(R.id.edt_height)
- edtLength = findViewById(R.id.edt_length)
- btnCalculate = findViewById(R.id.btn_calculate)
- tvResult = findViewById(R.id.tv_result)
- btnCalculate.setOnClickListener(this)
- }
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- edtWidth = findViewById(R.id.edt_width);
- edtHeight = findViewById(R.id.edt_height);
- edtLength = findViewById(R.id.edt_length);
- btnCalculate = findViewById(R.id.btn_calculate);
- tvResult = findViewById(R.id.tv_result);
- btnCalculate.setOnClickListener(this);
- }
- class MainActivity : AppCompatActivity(), View.OnClickListener {
- ...
- }
- public class MainActivity extends AppCompatActivity implements View.OnClickListener {
- ...
- }
Jangan khawatir! Silakan klik di atas baris merah tersebut, kemudian tekan tombol Alt + Enter (option + return pada Mac) atau menekan lampu merah yang muncul lalu pilih implement members (Kotlin) atau implement methods (Java).
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
- setContentView(R.layout.activity_main)
- ...
- }
- override fun onClick(v: View) {
- if (v.id == R.id.btn_calculate) {
- val inputLength = edtLength.text.toString().trim()
- val inputWidth = edtWidth.text.toString().trim()
- val inputHeight = edtHeight.text.toString().trim()
- val volume = inputLength.toDouble() * inputWidth.toDouble() * inputHeight.toDouble()
- tvResult.text = volume.toString()
- }
- }
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- ...
- }
- @Override
- public void onClick(View v) {
- if (v.getId() == R.id.btn_calculate) {
- String inputLength = edtLength.getText().toString().trim();
- String inputWidth = edtWidth.getText().toString().trim();
- String inputHeight = edtHeight.getText().toString().trim();
- double volume = Double.valueOf(inputLength) * Double.valueOf(inputWidth) * Double.valueOf(inputHeight);
- tvResult.setText(String.valueOf(volume));
- }
- }
- class MainActivity : AppCompatActivity(), View.OnClickListener {
- private lateinit var edtWidth: EditText
- private lateinit var edtHeight: EditText
- private lateinit var edtLength: EditText
- private lateinit var btnCalculate: Button
- private lateinit var tvResult: TextView
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
- setContentView(R.layout.activity_main)
- edtWidth = findViewById(R.id.edt_width)
- edtHeight = findViewById(R.id.edt_height)
- edtLength = findViewById(R.id.edt_length)
- btnCalculate = findViewById(R.id.btn_calculate)
- tvResult = findViewById(R.id.tv_result)
- btnCalculate.setOnClickListener(this)
- }
- override fun onClick(v: View) {
- if (v.id == R.id.btn_calculate) {
- val inputLength = edtLength.text.toString().trim()
- val inputWidth = edtWidth.text.toString().trim()
- val inputHeight = edtHeight.text.toString().trim()
- val volume = inputLength.toDouble() * inputWidth.toDouble() * inputHeight.toDouble()
- tvResult.text = volume.toString()
- }
- }
- }
- public class MainActivity extends AppCompatActivity implements View.OnClickListener {
- private EditText edtWidth, edtHeight, edtLength;
- private Button btnCalculate;
- private TextView tvResult;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- edtWidth = findViewById(R.id.edt_width);
- edtHeight = findViewById(R.id.edt_height);
- edtLength = findViewById(R.id.edt_length);
- btnCalculate = findViewById(R.id.btn_calculate);
- tvResult = findViewById(R.id.tv_result);
- btnCalculate.setOnClickListener(this);
- }
- @Override
- public void onClick(View v) {
- if (v.getId() == R.id.btn_calculate) {
- String inputLength = edtLength.getText().toString().trim();
- String inputWidth = edtWidth.getText().toString().trim();
- String inputHeight = edtHeight.getText().toString().trim();
- double volume = Double.valueOf(inputLength) * Double.valueOf(inputWidth) * Double.valueOf(inputHeight);
- tvResult.setText(String.valueOf(volume));
- }
- }
- }
-
telah selesai, silakan jalankan aplikasi dengan memilih menu Run → Run ‘app’ dari menu bar.
Selain cara di atas, Anda juga dapat menekan icon berikut di toolbar:
Kemudian akan muncul pilihan seperti ini:Itu tandanya ADB (Android Debugger) pada peranti yang Anda punya telah terhubung dengan Android Studio. Jika Anda tidak memiliki peranti, maka Anda dapat menggunakan emulator. Ikuti materinya di modul sebelumnya atau lihat materi di sini.
Kami merekomendasikan Anda menggunakan peranti Android sewaktu mengembangkan aplikasi. Selain karena beban memori pada peranti Anda akan jadi lebih rendah, pendekatan ini juga akan memungkinkan Anda untuk merasakan bagaimana aplikasi berjalan di device sebenarnya.
-
Pilih OK untuk menjalankan dan tunggu hingga proses building dan instalasi APK selesai. Jika sudah, seharusnya hasilnya akan seperti ini:

-
Silakan masukkan nilai panjang, lebar, dan tinggi kemudian tekan tombol Hitung dan hasilnya akan ditampilkan di objek textview tvResult. Namun masih ada sedikit masalah di sini, yaitu Anda tetap melakukan proses perhitungan walaupun salah satu nilainya kosong. Hal ini akan menyebabkan aplikasi force close karena perhitungan tidak dapat diproses. Maka untuk mengatasinya Anda akan menggunakan percabangan untuk mengecek apakah masing-masing EditText kosong atau tidak.
- Silakan buka kembali kelas MainActivity. Tambahkan kode berikut ke dalam metode onClicksebelum melakukan perhitungan.
- override fun onClick(v: View) {
- if (v.id == R.id.btn_calculate) {
- val inputLength = edtLength.text.toString().trim()
- val inputWidth = edtWidth.text.toString().trim()
- val inputHeight = edtHeight.text.toString().trim()
- var isEmptyFields = false
- if (inputLength.isEmpty()) {
- isEmptyFields = true
- edtLength.error = "Field ini tidak boleh kosong"
- }
- if (inputWidth.isEmpty()) {
- isEmptyFields = true
- edtWidth.error = "Field ini tidak boleh kosong"
- }
- if (inputHeight.isEmpty()) {
- isEmptyFields = true
- edtHeight.error = "Field ini tidak boleh kosong"
- }
- if (!isEmptyFields) {
- val volume = inputLength.toDouble() * inputWidth.toDouble() * inputHeight.toDouble()
- tvResult.text = volume.toString()
- }
- }
- }
- @Override
- public void onClick(View v) {
- if (v.getId() == R.id.btn_calculate) {
- String inputLength = edtLength.getText().toString().trim();
- String inputWidth = edtWidth.getText().toString().trim();
- String inputHeight = edtHeight.getText().toString().trim();
- boolean isEmptyFields = false;
- if (TextUtils.isEmpty(inputLength)) {
- isEmptyFields = true;
- edtLength.setError("Field ini tidak boleh kosong");
- }
- if (TextUtils.isEmpty(inputWidth)) {
- isEmptyFields = true;
- edtWidth.setError("Field ini tidak boleh kosong");
- }
- if (TextUtils.isEmpty(inputHeight)) {
- isEmptyFields = true;
- edtHeight.setError("Field ini tidak boleh kosong");
- }
- if (!isEmptyFields) {
- double volume = Double.valueOf(inputLength) * Double.valueOf(inputWidth) * Double.valueOf(inputHeight);
- tvResult.setText(String.valueOf(volume));
- }
- }
- }
- class MainActivity : AppCompatActivity(), View.OnClickListener {
- private lateinit var edtWidth: EditText
- private lateinit var edtHeight: EditText
- private lateinit var edtLength: EditText
- private lateinit var btnCalculate: Button
- private lateinit var tvResult: TextView
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
- setContentView(R.layout.activity_main)
- edtWidth = findViewById(R.id.edt_width)
- edtHeight = findViewById(R.id.edt_height)
- edtLength = findViewById(R.id.edt_length)
- btnCalculate = findViewById(R.id.btn_calculate)
- tvResult = findViewById(R.id.tv_result)
- btnCalculate.setOnClickListener(this)
- }
- override fun onClick(v: View) {
- if (v.id == R.id.btn_calculate) {
- val inputLength = edtLength.text.toString().trim()
- val inputWidth = edtWidth.text.toString().trim()
- val inputHeight = edtHeight.text.toString().trim()
- var isEmptyFields = false
- if (inputLength.isEmpty()) {
- isEmptyFields = true
- edtLength.error = "Field ini tidak boleh kosong"
- }
- if (inputWidth.isEmpty()) {
- isEmptyFields = true
- edtWidth.error = "Field ini tidak boleh kosong"
- }
- if (inputHeight.isEmpty()) {
- isEmptyFields = true
- edtHeight.error = "Field ini tidak boleh kosong"
- }
- if (!isEmptyFields) {
- val volume = inputLength.toDouble() * inputWidth.toDouble() * inputHeight.toDouble()
- tvResult.text = volume.toString()
- }
- }
- }
- }
- public class MainActivity extends AppCompatActivity implements View.OnClickListener {
- private EditText edtWidth, edtHeight, edtLength;
- private Button btnCalculate;
- private TextView tvResult;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- edtWidth = findViewById(R.id.edt_width);
- edtHeight = findViewById(R.id.edt_height);
- edtLength = findViewById(R.id.edt_length);
- btnCalculate = findViewById(R.id.btn_calculate);
- tvResult = findViewById(R.id.tv_result);
- btnCalculate.setOnClickListener(this);
- }
- @Override
- public void onClick(View v) {
- if (v.getId() == R.id.btn_calculate) {
- String inputLength = edtLength.getText().toString().trim();
- String inputWidth = edtWidth.getText().toString().trim();
- String inputHeight = edtHeight.getText().toString().trim();
- boolean isEmptyFields = false;
- boolean isInvalidDouble = false;
- if (TextUtils.isEmpty(inputLength)) {
- isEmptyFields = true;
- edtLength.setError("Field ini tidak boleh kosong");
- }
- if (TextUtils.isEmpty(inputWidth)) {
- isEmptyFields = true;
- edtWidth.setError("Field ini tidak boleh kosong");
- }
- if (TextUtils.isEmpty(inputHeight)) {
- isEmptyFields = true;
- edtHeight.setError("Field ini tidak boleh kosong");
- }
- if (!isEmptyFields) {
- double volume = Double.valueOf(inputLength) * Double.valueOf(inputWidth) * Double.valueOf(inputHeight);
- tvResult.setText(String.valueOf(volume));
- }
- }
- }
- }
- Jalan kembali aplikasi Anda dengan memilih menu Run → Run ‘app’ atau shortcut Shift + F10. Cobalah langsung menekan tombol HITUNG tanpa mengisi EditText, maka aplikasi Anda tidak akan force close dan akan muncul peringatan bahwa “Field ini tidak boleh kosong”.

- Apakah kita sudah selesai? Belum! Masih ada yang kurang. Ketika nilai volume sudah dihitung dan kemudian terjadi pergantian orientasi (portrait-landscape) pada peranti, maka hasil perhitungan tadi akan hilang. Hal ini karena di dalam Android, jika melakukan pergantian orientasi, Android akan memanggil fungsi onCreate kembali, sehingga data akan kembali menjadi seperti semula.
Untuk mengatasinya, tambahkan metode onSaveInstanceState() pada MainActivity dan sesuaikan seperti berikut:
- companion object {
- private const val STATE_RESULT = "state_result"
- }
- ...
- override fun onSaveInstanceState(outState: Bundle) {
- super.onSaveInstanceState(outState)
- outState.putString(STATE_RESULT, tvResult.text.toString())
- }
- private static final String STATE_RESULT = "state_result";
- ...
- @Override
- protected void onSaveInstanceState(Bundle outState) {
- super.onSaveInstanceState(outState);
- outState.putString(STATE_RESULT, tvResult.getText().toString());
- }
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
- setContentView(R.layout.activity_main)
- ...
- if (savedInstanceState != null) {
- val result = savedInstanceState.getString(STATE_RESULT) as String
- tvResult.text = result
- }
- }
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- ...
- if (savedInstanceState != null) {
- String result = savedInstanceState.getString(STATE_RESULT);
- tvResult.setText(result);
- }
- }
- Silakan jalankan kembali aplikasinya. Ulangi proses perhitungan seperti sebelumnya. Kemudian ganti orientasi peranti Anda. Jika sudah benar maka hasil perhitungan tidak akan hilang.
Bedah Kode
Pembahasan tentang layout xml
- xml version="1.0" encoding="utf-8"?>
- xmlns:android="http://schemas.android.com/apk/res/android"
Macam Views
- TextView, merupakan komponen view untuk menampilkan teks ke layar.
- EditText, merupakan komponen view untuk memberikan input teks.
- Button, merupakan komponen view untuk melakukan sebuah aksi klik.
- LinearLayout, merupakan komponen view bertipe viewgroup yang menjadi parent dari semua sub komponen view (sub view) di dalamnya. Komponen ini bersifat sebagai kontainer untuk komponen lain dengan orientasi secara vertikal atau horizontal.
- <TextView
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:text="@string/calculate"
- android:layout_marginBottom="16dp"/>


- match_parent, merupakan sebuah ukuran dimensi sebuah View yang disesuaikan dengan ukuran layar baik secara horizontal pada layout_width dan vertikal jika pada layout_height.
- wrap_content, merupakan ukuran dimensi sebuah View yang disesuaikan dengan ukuran konten di dalamnya baik secara horizontal pada layout_width dan vertikal jika pada layout_height.
- @string/calculate, merupakan sebuah value calculate berasal dari berkas strings.xml.
Apa itu @+id/ ?
- <Button
- android:id="@+id/btn_calculate"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:text="@string/calculate"/>
- android:id="@+id/btn_calculate"

Pembahasan tentang Logika Kode
- class MainActivity : AppCompatActivity()
- public class MainActivity extends AppCompatActivity
- , View.OnClickListener
- implements View.OnClickListener
- private lateinit var edtWidth: EditText
- private lateinit var edtHeight: EditText
- private lateinit var edtLength: EditText
- private lateinit var btnCalculate: Button
- private lateinit var tvResult: TextView
- private EditText edtWidth;
- private EditText edtHeight;
- private EditText edtLength;
- private Button btnCalculate;
- private TextView tvResult;
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
- setContentView(R.layout.activity_main)
- edtWidth = findViewById(R.id.edt_width)
- edtHeight = findViewById(R.id.edt_height)
- edtLength = findViewById(R.id.edt_length)
- btnCalculate = findViewById(R.id.btn_calculate)
- tvResult = findViewById(R.id.tv_result)
- btnCalculate.setOnClickListener(this)
- }
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- edtWidth = findViewById(R.id.edt_width);
- edtHeight = findViewById(R.id.edt_height);
- edtLength = findViewById(R.id.edt_length);
- btnCalculate = findViewById(R.id.btn_calculate);
- tvResult = findViewById(R.id.tv_result);
- btnCalculate.setOnClickListener(this);
- }
- setContentView(R.layout.activity_main)
- setContentView(R.layout.activity_main);
- edtWidth = findViewById(R.id.edt_width)
- edtWidth = findViewById(R.id.edt_width);
- class MainActivity : AppCompatActivity(), View.OnClickListener {
- ...
- btnCalculate.setOnClickListener(this)
- ...
- override fun onClick(v: View) {
- ...
- }
- public class MainActivity extends AppCompatActivity implements View.OnClickListener {
- ...
- btnCalculate.setOnClickListener(this);
- ...
- @Override
- public void onClick(View v) {
- ...
- }
Selain menggunakan implementation seperti di atas, Anda juga dapat mengimplementasikannya langsung seperti ini:
- btnCalculate.setOnClickListener {
- val inputLength = edtLength.text.toString().trim()
- val inputWidth = edtWidth.text.toString().trim()
- val inputHeight = edtHeight.text.toString().trim()
- ...
- }
- btnCalculate.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- String inputLength = edtLength.getText().toString().trim();
- String inputWidth = edtWidth.getText().toString().trim();
- String inputHeight = edtHeight.getText().toString().trim();
- ...
- }
- });
- val inputLength = edtLength.text.toString().trim()
- val inputWidth = edtWidth.text.toString().trim()
- val inputHeight = edtHeight.text.toString().trim()
- String inputLength = edtLength.getText().toString().trim();
- String inputWidth = edtWidth.getText().toString().trim();
- String inputHeight = edtHeight.getText().toString().trim();
- var isEmptyFields = false
- var isInvalidDouble = false
- when {
- inputLength.isEmpty() -> {
- isEmptyFields = true
- edtLength.error = "Field ini tidak boleh kosong"
- }
- inputWidth.isEmpty() -> {
- isEmptyFields = true
- edtWidth.error = "Field ini tidak boleh kosong"
- }
- inputHeight.isEmpty() -> {
- isEmptyFields = true
- edtHeight.error = "Field ini tidak boleh kosong"
- }
- }
- boolean isEmptyFields = false;
- boolean isInvalidDouble = false;
- if (TextUtils.isEmpty(inputLength)) {
- isEmptyFields = true;
- edtLength.setError("Field ini tidak boleh kosong");
- }
- if (TextUtils.isEmpty(inputWidth)) {
- isEmptyFields = true;
- edtWidth.setError("Field ini tidak boleh kosong");
- }
- if (TextUtils.isEmpty(inputHeight)) {
- isEmptyFields = true;
- edtHeight.setError("Field ini tidak boleh kosong");
- }
- if (!isEmptyFields) {
- val volume = inputLength.toDouble() * inputWidth.toDouble() * inputHeight.toDouble()
- tvResult.text = volume.toString()
- }
- if (!isEmptyFields) {
- double volume = Double.valueOf(inputLength) * Double.valueOf(inputWidth) * Double.valueOf(inputHeight);
- tvResult.setText(String.valueOf(volume));
- }
Pembahasan saveInstanceState
- override fun onSaveInstanceState(outState: Bundle) {
- super.onSaveInstanceState(outState)
- outState.putString(STATE_RESULT, tvResult.text.toString())
- }
- @Override
- protected void onSaveInstanceState(Bundle outState) {
- super.onSaveInstanceState(outState);
- outState.putString(STATE_RESULT, tvResult.getText().toString());
- }
- if (savedInstanceState != null) {
- val result = savedInstanceState.getString(STATE_RESULT) as String
- tvResult.text = result
- }
- if (savedInstanceState != null){
- String result = savedInstanceState.getString(STATE_RESULT);
- tvResult.setText(result);
- }
