Anda di halaman 1dari 186

Apa itu Android

Android adalah sistem operasi yang dikeluarkan oleh Google khususnya untuk
smartphone dan tablet. Berbagai macam produsen telah menggunakan Android
sebagai sistem operasi untuk device yang mereka produksi. Android juga mempunyai
store dimana terdapat 1 miliar pengguna aktif.

Mengapa Android
Muncul pertanyaan kenapa menggunakan Android ? Android memanjakan
penggunanya dengan fiturnya yang sangat canggih seperti tampilan ui yang bagus
baik dari segi user interface dan user experience, dapat digunakan sebagai alat
multimedia seperti pemutar musik dan video, dan juga menggunakan perangkat keras
seperti akselerometer, gyroscope dan sensor lainnya ke dalam aplikasi. Disamping itu
ada beberapa hal yang membuat Android sebagai sistem operasi yang memang layak
digunakan oleh pengguna atau dikembangkan oleh para developer, seperti yang akan
dijelaskan berikut ini.
Sistem Operasi SmartphoneTerpopuler
Sejak direlease pada tahun 2008, Android mengeluarkan beberapa versi dan hingga
saat ini yang terbaru adalah Nougat yang di release pada tahun 2016. Pada tahun
2013 Android menjadi best-selling OS pada tablet dan menjadi os yang majoritas
digunakan oleh pengguna smartphone. Tercatat pada tahun 2016 store Android
memiliki lebih dari 2.7 juta aplikasi dan lebih dari 2 miliar penggunaaktif tiap bulannya.
Android menarik untuk para perusahaan teknologi yang membutuhkan barang siap
jadi, biaya rendah dan kustomisasi os untuk perangkat teknologi tinggi mereka.
Dengan beberapa kelebihan tersebut membuat perusahaan-perusahaan besar
mengeluarkan produknya dengan menggunakan sistemoperasi Android.
Source code dari Android dikeluarkan oleh Google dengan memiliki lisensi open
source, sehingga menarik para komunitas developer dan entusias untuk
menggunakannya dalam project komunitas.

Store
Aplikasi Android bisa di distribusikan dengan menggunakan web, copy apk, email dan
store. Store Android yaitu Google Play merupakan cara termudah bagi para developer
untuk medistribusikan aplikasinya ke pasar yang memiliki jutaan pengguna.

Google play merupakan store resmi Android yang dikelola oleh Google, pengguna
bisa mencari dan download aplikasi yang di kembangkan dengan menggunakan
Android Software Development Kit. Disamping aplikasi beberapa servis yang
ditawarkan di dalam Google Play adalah media digital, music, buku, majalah, film dan
program televisi.
Bagaimana para developer memonetisasi aplikasi yang ada di dalam Google Play?
Strategi monetisasi aplikasi yang di tawarkan Google Play bermacam-macam dimulai
dari paid distribution (app berbayar), in-app produk, subscriptions, dan ads. Tentunya
developer harus mengikuti aturan yang ada untuk memastikan bahwa pengguna
mendapatkan user experience yang paling bagus.

Development Kit untuk developer


Android Software Development Kit (SDK) merupakan kit yang bisa digunakan oleh
para developer untuk mengembangkan aplikasi berbasis Android. SDK di dalamnya
terdapat beberapa tools untuk mengembangkan aplikasi seperti debugger, software
libraries, emulator, dokumentasi, sample code dan tutorial.
Bahasa pemrograman yang sering digunakan untuk mengembangkan aplikasi
Android adalah Java, namun ada beberapa Bahasa lainnya yang juga support untuk
mengembangkan aplikasi Android seperti C++, dan Go. Dan pada Google IO 2017
menjadikan Kotlin sebagai Bahasa yang disupport resmi oleh Google.

Berbicara tentang pemrograman tentunya tidak lepas dari Integrated Development


Environment(IDE) yang bisa dipakai oleh para Developer. Pada 2014 Google
mengeluarkan IDE yang bernama Android Studio yang berbasikan dari Intellij IDEA.
Dengan menggunakan Android Studio para developer dapat membuat aplikasi dari
nol hingga publish ke dalam store. Android Studio juga mempunyai beberapa fitur
built-in yang sangat membantu para developer untuk memaksimalkan proses
pembuatan aplikasi seperti Gradle, Code Completion, dan terintegrasi dengan
beberapa services dari Google seperti Firebase.

Sejarah Android
Dibawah ini berupa list sejarah dari Android yang resmi di release oleh Google.
First
Release API
Version Code name DVM/ART Distribution devices to
date level
run version

7.1 October 4, Pixel, Pixel


25 ART 0.6%
2016 XL
Nougat
7.0 August 22,
24 ART 8.9%
2016 Nexus 5X,
6.0 October 5, Nexus 6P
Marshmallow 23 ART 31.2%
2015
5.1 March 9,
22 ART 22.6% Android One
2015
Lollipop
5.0 November 3,
21 ART 2.1.0 8.2% Nexus 6
2014
4.4 October 31, DVM (and
KitKat 19 18.1% Nexus 5
2013 ART 1.6.0)
4.3 July 24, Nexus 7
18 DVM 1.3%
2013 2013
4.2 Jelly Bean November Nexus 4,
17 DVM 4.4%
13, 2012 Nexus 10
4.1 July 9, 2012 16 DVM 3.1% Nexus 7
4.0 Ice Cream December Galaxy
15 DVM 0.8%
Sandwich 16, 2011 Nexus
2.3 February 9,
Gingerbread 10 DVM 1.4.0 0.8% Nexus S
2011
Sources : https://en.wikipedia.org/wiki/Android_(operating_system)
Java
Salah satu Bahasa yang bisa digunakan untuk development Android adalah Java.
Selain Java ada beberapa Bahasa lain yang bisa digunakan seperti C/C++, Go, dan
pada May 2017 Google resmi support Kotlin.
Pada akademi ini kita hanya akan fokus menggunakan Java sebagai Bahasa
pemrograman yang digunakan. Oleh karena itu maka kita install dulu software yang
harus kita gunakan untuk coding (menuliskan baris code), siapkan senjata Anda
sebelum berperang.
Yang harus diinstall adalah Java Development Kit yang bisa kita dapatkan pada link
berikut:

 http://www.oracle.com/technetwork/java/javase/downloads/index-jsp-
138363.html

Biasanya muncul pertanyaan? Apakah JRE cukup? Tidak, JRE adalah Java Runtime
Environment yang berfungsi sebagai Virtual Machine untuk menjalankan program
Java. Sedangkan JDK merupakan Java SE Development Kit, dimana JRE juga di ada
di dalamnya. Dan yang lebih penting adalah di dalamnya terdapat compiler dan tools
untuk membuat dan compile program.
Sederhananya JRE untuk menjalankan program, JDK untuk membuat program.
Mari kita mulai dengan proses instalasi dari JDK.

1. Langsung saja buka link di atas menggunakan browser Anda, dan pilih Java
Platform (JDK), tampilan dari layout download dari JDK.
2. Lalu pilihlah yang sesuai dengan device dan os yang Anda pakai.

3. Setelah proses download selesai, langsung install ke device Anda dan ikuti
petunjuknya sampai selesai.

Android Studio
Pada akademi kali ini kita akan menggunakan Android Studio sebagai IDE (Integrated
Development Environment). Android Studio di release 16 May 2013 pada Google IO.
Android Studio berbasiskan JetBrains Intellij IDEA, dan dikhususkan untuk
mengembangkan software berplatform Android.
Untuk Android Studio bisa download dari website resmi google :

 https://developer.android.com/studio/index.html

Mari langsung saja kita mulai instalasi dari Android Studio.


ampilan jendela pertama kali ketika Android Studio. Untuk memulai project baru
pilihlah “Start a new Android Project”.

1. Dalam dialog ini kita bisa memberi nama dari aplikasi kita, dan company
domain. Company domain akan di gunakan dalam identifikasi unik dari
aplikasi kita ketika sudah di-publish. Kita juga dapat mengganti dari direktori
dimana project kita akan disimpan.

2. Dialog selanjutnya adalah target devices, di dalam dialog ini kita bisa memilih
target devices dari aplikasi yang akan kita buat. Kita juga bisa mengganti nilai
minimum SDK yang akan di kover oleh aplikasi kita.

3. Dialog selanjutnya adalah default template. Terdapat beberapa template yang


bisa kita gunakan seperti Empty Activity, Login Activity, Navigation Drawer
Activity, dan lain-lain.

4. Dialog selanjutnya adalah nama dari activity yang pertama kali kita buat.

Android Manifest
Manifest adalah salah satu file yang harus ada di dalam sebuah project Android.
Manifest berfungsi sebagai file yang memberikan informasi penting dari sebuah
aplikasi ke sistem Android. Sistem perlu mengetahui apa yang akan digunakan oleh
aplikasi sebelum bisa mulai dijalankan.
Beberapa fungsi yang ada di dalam manifest adalah sebagai berikut.

 Nama Package

1. <manifest xmlns:android="http://schemas.android.com/apk/res/android"
2. package="com.dicoding.myapplication">

Package name merupakan sebagai identitas unik dari sebuahaplikasi.


Identitas ini juga yang akan digunakan di dalam store untuk membedakan
suatu aplikasi dengan aplikasi lainnya. Jangan pernah mengganti value di
dalam package karena nantinya akan dikenali sebagai aplikasi yang lainjika
sudah masuk ke dalam store.

 Komponen Aplikasi
Berfungsi untuk mendiskripsikan komponen dari aplikasi mulai dari activity,
services, broadcast receiver, dan content provider.

1. <application
2. android:allowBackup="true"
3. android:icon="@mipmap/ic_launcher"
4. android:label="@string/app_name"
5. android:roundIcon="@mipmap/ic_launcher_round"
6. android:supportsRtl="true"
7. android:theme="@style/AppTheme">
8. <activity android:name=".MainActivity">
9. <intent-filter>
10. <action android:name="android.intent.action.MAIN" />
11.
12. <category android:name="android.intent.category.LAUNCHER
" />
13. </intent-filter>
14. </activity>
15.
16. <service
17. android:name=".MyIntentService"
18. android:exported="false" />
19.
20. <receiver
21. android:name=".MyReceiver"
22. android:enabled="true"
23. android:exported="true"></receiver>
24. </application>

Komponen aplikasi semuanya berada di antara tag <application>. Disini juga


berfungsi sebagai penamaan kelas yangmeng-implement komponen dan
mendeskripsikan kemampuannya seperti intent-filter, dimana fungsinya
mendeskripsikan bahwa komponen itu adalah yang pertama kali dijalankan.

 Permission
Mendeklarasikan permission apa saja yang harus dimiliki oleh aplikasi untuk
akses ke dalam komponen API seperti internet, external storage, contact, dan
juga untuk berinteraksi kepada aplikasi lainnya.
Gradle
Gradle merupakan open source build automation system. Automation system
berguna untuk mengotomatisasi proses pembuatan dari software build dan proses-
proses terkait lainnya termasuk compile source code menjadi binary code,
packaging binary code, dan menjalankan automated test.

build.gradle (Project: MyApplication)


Merupakan software build tingkat teratas yang meliputi keseluruhan dari project dari
sebuah aplikasi. Di dalamnya berisi konfigurasi semua modul yang ada di dalam
project.
build.gradle (Module: app)
Merupakan software build yang ada pada setiap modul di dalam project sebuah
aplikasi. Beberapa konfigurasi yang di edit di antaranya adalah android settings,
defaultConfig dan productFlavors, buildTypes, dan dependencies.

1. apply plugin: 'com.android.application'


2.
3. android {
4. compileSdkVersion 25
5. buildToolsVersion "25.0.2"
6. defaultConfig {
7. applicationId "com.dicoding.myapplication"
8. minSdkVersion 21
9. targetSdkVersion 25
10. versionCode 1
11. versionName "1.0"
12. testInstrumentationRunner "android.support.test.runner.AndroidJUnit
Runner"
13. }
14. buildTypes {
15. release {
16. minifyEnabled false
17. proguardFiles getDefaultProguardFile('proguard-android.txt'), '
proguard-rules.pro'
18. }
19. }
20. }
21.
22. dependencies {
23. compile fileTree(dir: 'libs', include: ['*.jar'])
24. androidTestCompile('com.android.support.test.espresso:espresso-core:2.2
.2', {
25. exclude group: 'com.android.support', module: 'support-annotations'
26. })
27. compile 'com.android.support:appcompat-v7:25.3.1'
28. compile 'com.android.support.constraint:constraint-layout:1.0.2'
29. testCompile 'junit:junit:4.12'
30. }

 Android Settings
Di dalam block android kita bisa menetapkan compileSDKVersion dan
buildToolsVersion.
 Default Config
Di dalamnya terdapat properties seperti applicationID, minSdkVersion,
targetSdkVersion dan test information.
 Build Types
Di dalamnya terdapat properties dari debuggable, ProGuard enabling, debug
signing, version name suffix dan test information.
 Dependencies
Di dalamnya terdapat `informasi tentang library yang digunakan oleh aplikasi.

Sync Project
Setiap kali terjadi perubahan informasi di dalam build.gradle maka kita harus
melakukan sinkronisasi terlebih dahulu. Tombol sync now akan muncul pada
sebelah kanan atas ketika terjadi perubahan.

Setelah proses sinkronisasi selesai maka akan muncul informasi pada log apakah
proses sinkronisasi berhasil atau tidak.
Testing aplikasi sudah merupakan kewajiban yang harus dilakukan oleh seorang
developer. Proses running atau debugging bisa dilakukan dengan dua cara yaitu
dengan emulator atau device asli. Baik emulator atau device asli memiliki kelebihan
dan kekurangan masing-masing, kita sebagai developer tinggal memilih mana yang
sesuai dengan keperluan kita.
Running menggunakan emulator
Ikuti langkah-langkah berikut untuk run aplikasi kita dengan menggunakan emulator
built-in dari Android Studio.

1. Jalankan icon run, kemudian akan muncul dialog seperti ini. Mari kita coba buat
emulator baru dengan memilih Create New Virtual Device.
2. Akan muncul dialog dengan pilihan beberapa emulator device yang bisa
langsung anda gunakan.
3. Jika anda ingin membuat spesifikasi hardware sendiri bisa dengan memilih
pilihan New Hardware Profile. Maka akan muncul dialog seperti dibawah ini.
Konfigurasi hardware terserah dengan preferensi dari pengguna, yang perlu
diingat adalah gunakanlah konfigurasi emulator yang sesuai dengan
kemampuan dari laptop atau computer yang Anda gunakan. Run emulator
perlu di perhatikan karena emulator akan memakan resource yang cukup
lumayan banyak.
4. Anda dapat membuat hardware emulator baru atau bisa juga memilih dari
hardware emulator yang sudah ada. Setelah memilih hardware emulator
langsung ke langkah selanjutnya yaitu akan muncul dialog seperti ini.
Pada dialog ini anda akan memilih versi android dari emulator yang akan anda
buat. Pada dialog diatas dipilih versi yang sudah terdownload yaitu Nougat.
Tombol download di sebelah kanan versi menunjukkan bahwa anda perlu men-
download-nya terlebih dahulu jika ingin menggunakannya.
5. Selanjutnya klik Next, dan akan muncul dialog verify configuration. Pada dialog
ini anda bisa sekali lagi memverifikasi configurasi dari emulator yang anda pilih.
Di bawah kiri ada tombol Show Advanced Settings, coba anda klik dan akan
muncul tampilan dialog baru seperti ini.
Dari tampilan advanced setting anda bisa kustomisasi hardware yang telah kita
pilih sebelumnya.
6. Jika sudah selesai klik finish dan langsung launch emulatornya dengan
menekan tombol hijau yang ada di sebelah kanan.
7. Okay, selesai setting emulatornya dan bisa langsung dijalankan.
Catatan :
Jika muncul warning bahwa haxm not installed bisa langsung download
dengan mengikuti link download yang disediakan.
Jika muncul warning bahwa VT-x disabled in BIOS maka anda perlu
restart komputer anda, kemudian masuk ke layar BIOS, dan ubah
virtualization-nya menjadi enabled.

Run dengan device


Untuk run atau debugging yang paling disarankan kepada para developer adalah
dengan menggunakan device smartphone asli. Run dengan menggunakan device
memiki beberapa kelebihan jika dibandingkan dengan emulator yaitu :

1. Lebih cepat
2. Fitur seperti geo-location, push notif bisa digunakan
3. Bisa mengetahui daya serap baterai terhadap aplikasi
4. Lebih mudah

Dengan menggunakan device smartphone asli maka kita dapat mengetahui keadaan
(environment) aplikasi ketika dijalankan di device asli. Dengan memastikan bahwa
aplikasi kita berjalan secara wajar di device asli maka sudah cukup memberikan
jaminan kepada aplikasi kita ketika nantinya di pasarkan (store). Akan tetapi kadang
kala dengan hanya run di satu device belum cukup untuk merepresentasikan
berjalannya aplikasi kita di store, dikarenakan banyaknya model device Android yang
ada di pasaran saat ini. Tapi kita tidak akan membahas masalah ini di dalam akademi
kita.
Mari ikuti langkah-langkah berikut untuk run atau debug di dalam device. Tampilan
dari langkah berikut bisa dipastikan akan berbeda dengan device yang Anda pakai,
akan tetapi secara garis besar langkahnya akan sama meskipun berbeda device

1. Pastikan device yang akan dipakai sesuai dengan target SDK atau paling tidak
min SDK version dari aplikasi kita.
2. Buka setting dan masuk ke dalam menu About. Di dalam about cari informasi
tentang build number.
3. Kemudian tekan build number sebanyak 7 kali.
4. Kembali ke menu setting di awal dan akan muncul menu baru di bawah about
yaitu Developer Options. Selamat anda sudah resmi menjadi seorang
Developer Android.
5. Masuk ke dalam menu Developer options dan pastikan opsi USB Debugging
Mode sudah nyala.

6. Oke selesai setting pada device langsung saja koneksikan dengan laptop atau
computer yang anda pakai.


Hal terakhir setelah mengembangkan aplikasi di Android adalah membuat file
executable dalam bentuk format APK (Android Application Package) yang dapat
didistribusikan agar aplikasi kita dapat sampai ke tangan pengguna. Jika kamu belum
mengerti tentang apk, ini seperti file exe di windows atau ipa di iOS yang akan
didapatkan oleh pengguna untuk melakukan instalasi (pemasangan) aplikasi di device
android. File inilah yang akan nantinya kamu upload ke Google Play agar pengguna
bisa mendownload aplikasi kamu. Kelebihan dari file apk ini adalah kemampuannya
untuk didistribusikan melalui non market aplikasi, bisa melalui website, email, bahkan
flashdisk. Namun, jika aplikasi mu ingin lebih menjangkau lebih jauh pengguna
disarankan tetap melakukan publish aplikasi kamu ke Google Play Store.
Cara membuat file apk di android pun cukup mudah via wizard atau via command line.
Pada sesi kali ini kita akan memfokuskan pada penggunaan wizard untuk melakukan
proses generate apk yang akan kita bagi menjadi dua :

1. Dengan menggunakan default keystore


2. Dengan menggunakan custom keystore

Sebelum memulai kami yakin kamu masih mempertanyakan tentang ‘mahluk’


bernama keystore itu seperti apa, baik, keystore adalah sebuah file binary yang berisi
informasi tentang satu atau lebih private key. Ini lebih mengarah pada konsep
pengamanan apk yang kita buat yang di generate dengan sertifikat berbasis public
dan private key. Konsep umumnya sebagai berikut : Sistem operasi android
membutuhkan semua apk di signed / digenerate dengan menggunakan sebuah
sertifikat sebelum aplikasi atau apk-apk tersebut dipasang ke dalam device. Proses
penggunaan public dan private key berlangsung selama developer melakukan
generasi (signed) apk untuk versi debug maupun untuk versi production (release).
Sebuah sertifikat digital public key atau juga disebut identify certificate berisi informasi
tentang dirinya sendiri dan private key yang bisa digunakan dan juga termasuk
metadata dari pemilik certificate tersebut dalam hal ini developer yang melakukan
proses pembuatan aplikasi. Public key ini secara otomatis akan dilampirkan dalam file
apk ketika proses signed/generate apk dilakukan oleh gradle melalui signing tools
yang disediakan oleh android studio. Public key bersifat identifier unik yang hanya
berasosiasi dengan file project android yang digunakan dan file keystore terkait. Selain
untuk menjaga keamanan dari apk yang dibuat ini juga akan termasuk pada
konsistensi dan menjaga originalitas ketika apk diupdate di Google Play Store. Ingat
apk hanya bisa diupdate jika keystore pertama kali upload sama dengan keystore ke
n kali upload. Kegunaan keystore sangat banyak dua diantaranya yang paling
terpenting ialah :

 Untuk integrasi ke layanan Google seperti Google Maps dengan menggunakan


nilai hash (diggest SHA1) didalamnya.
 Untuk integrasi ke layanan api facebook dengan menggunakan keyhash
base64 yang terkandung didalam keystore.

Keystore merupakan sebuah file penting yang kamu harus benar-benar bisa menjaga,
terlebih jika aplikasi buatan kamu adalah calon-calon aplikasi dengan jumlah
download yang besar dan memberikan manfaat banyak. Karna kalau kamu lalai
akibatnya adalah file apk kamu tidak dapat terupdate dan hal terburuknya kamu harus
melakukan dari awal lagi. Berikut adalah tips yang bisa kamu pahami untuk
mengamankan keystore :

1. Plih password yang sulit ditebak, kombinasikan angka, alphabet dan simbol
dalam membuatnya.
2. Bedakan antara keystore password dan keypassword ketika membuat file apk
dengan kustom keystore.
3. Jangan memberikan keystore kepada orang yang tidak dipercaya apalagi kamu
meletakannya didalam file project aplikasi.

Letakan ditempat yang kamu ingat dan pastikan aman.


Seperti biasa untuk membuat kamu lebih paham tentang ini kami menyarakan kamu
untuk membaca materi lanjutan di tautan berikut :

 App Signing

Jika kamu ingin menemukan dimana default keystore kamu yang berupa
debug.keystore kamu bisa mendapatkannya di ~/.android/debug.keystore Pada mac
dan C:\User\YourUser\.android\debug.keystore pada windows.
Tenang pada latihan kali ini kita sama sekali tidak melakukan pengkodean. Mari kita
mulai dengan yang pertama :

1. Buka salah satu project android associate favoritmu, misal My Broadcast


Receiver.
2. Sekarang klik menu Build → Build APK

3. Lalu perhatikan secara otomatis pada status bar gradle akan menjalankan
sebuah proses untuk melakukan proses generate apk. Proses ini bergantung
pada seberapa kompleks aplikasi kamu dan seberapa banyak dependensi
dengan library yang kamu gunakan.
4. Ketika berhasil maka di sudut kanan atas android studio kamu akan muncul
notifikasi sebagai berikut :

Sekarang tinggal kamu klik link yangterdapat pada notifikasi tersebut dan
secara otomatis akan diarahkan dimana file apk tersebut berada biasanya pada
struktur seperti berikut project-name/module-name/build/outputs/apk/dan jika
disesuaikan dengan project yang sedang digunakan maka akan menjadi
sepertiberikut MyBroadcastReceiver/app/build/outputs/apk/apk-
debug.apk
5. Tadaaaa… sekarang kamu sudah berhasil membuat apk dengan
menggunakan default keystore. Ingat, apk yang baru saja kamu generate
akan ditolak oleh Google Play Store jika kamu mencoba mengupload dan
publish ke Google Play Store. Agar dapat diterima oleh Google Play Store
kamu harus melakukan signed atau generate dengan menggunakan kustom
keystore.
6. Sekarang coba kamu pindahkan file apk yang barusan kamu buat ke dalam
device kamu (tentunya dengan yang sebelumnya kamu copot (uninstall)
terlebih dahulu) dan dengan file explorer pada device kamu, temukan dan
lakukan instalasi aplikasi seperti biasa dan whoillaaa aplikasi android kamu
bisa terinstal di device! File ini bisa kamu berikan ke kakak, nenek, mbah atau
opung kamu untuk memamerkan kalau kamu sudah bisa bikin aplikasi di
Android yeahh.
7. Mudah bukan ? Sekarang kita lanjut membuat apk dengan kustom keystore.
8. Langkah pertama klik Build → Generate Signed APK
9. Selanjutnya klik next pada dialog dibawah ini :

10. Selanjutnya, pilih create new… pada form yang tampil lengkapi isian
didalamnya menjadi sebagai berikut (ingat ini hanya contoh)

Berikut penjelasan field per fieldnya :


o Keystore path : Tentukan dimana kamu menyimpan keystore kamu,
beri nama dan disini kami membuat folder baru bernama keystore di
direktori dicoding
o Password : Isikan keystore password minimail 6 digit dan
bedakan dengan keypassword dibawahnya
o Alias : Alias dari keystore
o Password : keypassword
o Validity : Berapa lama kamu keystore kamu akan valid
(dalam hitungan tahun)
o Firstname hingga Country Code : Isikan meta data, dan ini penting
dengan memberikan data yang valid.
11. Setelah selesai klik OK.
12. Dialog yang diawal akan secara otomatis terisi ketika kamu sudah berhasil
mengisi form sebelumnya. Klik next untuk melanjutkan.

13. Jika ditanyakan tentang password seperti ini, masukan password yang kamu
gunakan untuk device laptop mu.

14. Selanjutnya tentukan dimana kamu menyimpan apk yang dihasilkan. Disini
kami membiarkan secara default. Klik finish untuk memulai signed/generate
apk.

15. Perhatikan pada gradle proses di status bar bagian bawah untuk melihat
progress signed/generate apk

16. Ketika berhasil maka notifikasi seperti berikut akan tampil :

17. Selamat apk production kamu berhasil digenerate. Ingat, ini dilakukan ketika
kamu ingin melakukan upload/reupload plus publish aplikasi kamu di Google
Play dan jangan lupa setiap kamu melakukan update aplikasi jangan lupa untuk
merubah nilai dari
1. versionCode 1 (Incremental)
2. versionName "1.0"

Sebelum melakukan upload update aplikasi. Kalau tidak dirubah siap-siap apk
baru yang akan kamu upload akan ditolak oleh Google Play Store.
Activity Lifecycle

Developer yang baik, harus mengetahui secara detail tentang lifecycle


sebuah Activity untuk melakukan aksi yang tepat, terutama ketika terjadi perubahan
state dari Activity. Callback methods yang ada dapat digunakan untuk melakukan
beragam proses terkait state dari Activity. Misal melakukan semua inisialisasi
komponen di onCreate(), melakukan disconnect terhadap koneksi ke server
pada onStop() atau onDestroy() dan lain sebagainya. Pemahaman yang baik
tentang daur hidup Activity akan membuat implementasi fungsi dari rancangan
aplikasi anda menjadi lebih baik. Hal ini juga meminimalisir terjadinya error/bug/force
close yang tidak diinginkan.
Last In, First Out (LIFO)

Gambar 1 Gambar 2 Gambar 3


Aktif: Activity 1 Aktif: Activity 2 Activity 1
onCreate() → onStart() → onResume() Stack append: onStop() → onRestart() → onStart() → o
Activity 2
[ onResume() ]
Aksi: Klik Button1 (Pindah) Aksi: Klik Aktif: Activity 1
Hardware Back
Button
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. Activity pertama dijalankan setelah pengguna meluncurkan aplikasi anda
melalui icon aplikasi di layar device. Activity yang ada saat ini berada pada
posisi Activity running setelah melalui beberapa
state onCreate() → onStart() → onResume() dan masuk ke dalam sebuah
stack Activity.
Bilamana dari Activity pertama anda menjalankan Activity kedua melalui klik sebuah
tombol (button); posisi state dari Activity pertama anda, berada pada posisi stop dan
method callback onStop() akan dipanggil. Ini terjadi karena Activity sebelumnya
sudah tidak berada pada layar foreground / tidak lagi ditampilkan namun semua
informasi terakhir pada Activity pertama akan disimpan secara
otomatis. Activity kedua masuk ke dalam stack dan menjadi Activity terakhir yang
masuk.
Gambar 2: Activity kedua sudah muncul di layar sekarang. Lalu dari Activity kedua
ini anda menekan tombol back pada physical button menu utama atau memanggil
method finish() maka Activity kedua anda akan di pop up keluar dari stack dan
state Activity ini akan berada pada destroy, tentunya method onDestroy() akan
dipanggil. Inilah mengapa disebut Last In, First Out.Activity kedua menjadi yang
terakhir masuk stack dan yang paling pertama keluar dari stack.
Gambar 3: Activity Pertama akan dimunculkan kembali di layar setelah melalui
beberapa state dengan rangkaian callback method yang
terpanggil, onStop() → onRestart() → onStart() → onResume().
Detailnya dapat anda baca disini :

 LifeCycle

Saving Activity State


Ketika sebuah activity mengalami onPause kemudian onResume maka state dari
sebuah activity tersebut dapat terjaga. Ini karena obyek Activity masih tersimpan di
memory sehingga dapat dikembalikan statenya. Dengan menjaga state
dari Activity tersebut maka perubahan pada Activity yang dilakukan oleh user ketika
activity kembali ke foreground atau onResume akan tetap seperti saat user berpindah
activity bahkan berpindah aplikasi.
Akan tetapi ketika sistem menghancurkan Activity untuk keperluan memori (misalnya
karena memori habis), maka obyek activity dihancurkan. Dengan dihancurkannya
sebuah obyek Activity maka ketika Activity ingin ditampilkan kembali diperlukan
proses re-create activity yang dihancurkan. Karena ada kemungkinan terjadinya
proses tersebut maka perubahan yang dilakukan pada activity perlu disimpan terlebih
dahulu. Disinilah method onSaveInstanceState() digunakan.
Dalam onSaveInstanceState terdapat bundle yang dapat digunakan untuk
menyimpan informasi dengan memanfaatkan fungsi
seperti putString() dan putInt(). Bundle dikirimkan
pada onCreate dan onRestoreInstanceState ketika Activity di-restart. Dengan
menggunakan bundle yang dikirimkan maka activity dapat mengisi kembali perubahan
yang terjadi saat onCreate atau dengan meng-override onRestoreInstanceState.

Proses penghancuran aplikasi bukan hanya pada saat ketika sistem menghancurkan
activity karena membutuhkan memori untuk proses lain; akan tetapi terjadi juga ketika
terjadi perubahan konfigurasi seperti orientation changes, keyboard avalaibility,
dan language. Beberapa proses tersebut ketika terjadi akan
menjalankan onDestroy kemudian langsung memanggil onCreate. Behavior
tersebut dimaksudkan agar activity dapat menyesuaikan dengan konfigurasi yang
baru seperti menyesuaikan ukuran layar.
Hal yang perlu diingat ketika
menggunakan onSaveInstanceState adalah Bundle tidak diperuntukkan
menyimpan data yang besar seperti bitmaps dan Bundle harus melalui proses
serialize serta deserialize yang akan memakan memori.
Tujuan

Codelab ini bertujuan untuk mengimplementasikan komponen Activity pada


aplikasi pertama yang anda bangun sehingga dapat memberikan gambaran tentang
bagaimana Activity ditampilkan. Kemudian anda memberikan Interaksi di dalamnya
seperti memberi input dan mengklik sebuah tombol.

Logika Dasar

Melakukan input ke dalam obyek TextBox → Melakukan validasi input →


Melakukan perhitungan volume balok ketika tombol hitung diklik

Codelab Perhitungan Volume

1. Buat Project Baru dengan klik File -> New -> New Project... pada Android
Studio anda

2. Setelah muncul Jendela Create New Project, kemudian atur nama


aplikasi dan domain perusahaan/website anda. Sebaiknya jangan sama
dengan apa yang ada dicontoh. Dan jangan lupa pula untuk menentukan
lokasi project.

3. Kemudian pilih tipe device untuk aplikasi beserta target minimum SDK yang
akan kita gunakan. Pilihan target Android SDK yang kita pilih akan
mempengaruhi banyaknya device yang bisa menggunakan aplikasi buatan
kita. Disini kita pilih untuk tipe device Phone and Tablet dengan minimum
SDK diset ke Level 15 (Ice Cream Sandwich)/ Klik Next untuk melanjutkan.
4. 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 :
Add No Activity : Tidak ada Activity yang ditambahkan
Basic Activity : Activity dengan template komponen
material design seperti FloatingActionButton
Empty Activity : Activity dalam bentuk yang paling dasar
Fullscreen Activity : Activity fullscreen tanpa status bar
Google AdMob Ads Activity : Activity dengan default konfigurasi 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 device tablet
Navigation Drawer Activity : Activity dengan tampilan side bar menu
Scrolling Activity : Activity dengan kemampuan Scroll konten
didalamnya secara vertical
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) dan dengan menggunakan komponen ViewPager
Saat ini kita pilih tipe Empty Activity, klik Next untuk melanjutkan.
5. Selanjutnya, tentukan nama Activity pertama kita, saat ini kita biarkan pada
kondisi apa adanya. Ingat, jika suatu saat nanti kita ingin melakukan
penambahan Activity, best practice nya adalah dengan menambahkan
Activity setelah kata nama kelas yang akan kita buat. Misal: ProfileActivity,
SettingsActivity dan lain sebagainya. Klik Finish untuk menyelesaikan.
6. Selamat!, Anda telah berhasil membuat sebuah project baru Android. Layar
anda pasti akan seperti dibawah ini:

7. Di sebelah kanan anda adalah workspace dimana Activity anda berada dan
bernama MainActivity.java dengan layoutnya activity_main.xml. Di sebelah
kiri anda terdapat struktur project anda dimana nanti kita akan banyak
menambahkan berbagai komponen, asset dan library. Untuk lebih mengenal
Android Studio lebih dalam silakan baca materi
ini https://developer.android.com/studio/intro/index.html

Selanjutnya kita akan mulai melakukan pengkodean aplikasi atau lebih enaknya
disebut ngoding. Berikut flow umumnya.
Ngoding Layout untuk User Interface aplikasi
Ngoding Activity untuk menambahkan logika aplikasi

Jangan ngetik saja atau ngoding polos, Gunakan ctrl + space untuk
menggunakan code completion dari Android Studio agar mengoptimasi import
package dari komponen yang digunakan.
Dilarang Keras untuk copy - paste! Ngoding pelan-pelan akan membuat anda
lebih jago di masa depan.

Selamat ngoding!

Menambahkan Code Sederhana pada Layout Activity

1. Silahkan klik tab file activity_main.xml pada workspace anda


(res/Layout/activity_main.xml), dan silakan ikuti baris-baris berikut:

1. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/andr
oid"
2. xmlns:tools="http://schemas.android.com/tools"
3. android:layout_width="match_parent"
4. android:layout_height="match_parent"
5. android:paddingBottom="@dimen/activity_vertical_margin"
6. android:paddingLeft="@dimen/activity_horizontal_margin"
7. android:paddingRight="@dimen/activity_horizontal_margin"
8. android:paddingTop="@dimen/activity_vertical_margin"
9. android:orientation="vertical"
10. tools:context="com.dicoding.associate.barvolume.MainActivity">
11. <TextView
12. android:layout_width="match_parent"
13. android:layout_height="wrap_content"
14. android:text="Panjang"
15. android:layout_marginBottom="@dimen/activity_vertical_margin
"/>
16. <EditText
17. android:id="@+id/edt_length"
18. android:layout_width="match_parent"
19. android:layout_height="wrap_content"
20. android:inputType="numberDecimal"
21. android:lines="1"
22. android:layout_marginBottom="@dimen/activity_vertical_margin
"/>
23. <TextView
24. android:layout_width="match_parent"
25. android:layout_height="wrap_content"
26. android:text="Lebar"
27. android:layout_marginBottom="@dimen/activity_vertical_margin
"/>
28. <EditText
29. android:id="@+id/edt_width"
30. android:layout_width="match_parent"
31. android:layout_height="wrap_content"
32. android:inputType="numberDecimal"
33. android:lines="1"
34. android:layout_marginBottom="@dimen/activity_vertical_margin
"/>
35. <TextView
36. android:layout_width="match_parent"
37. android:layout_height="wrap_content"
38. android:text="Tinggi"
39. android:layout_marginBottom="@dimen/activity_vertical_margin
"/>
40. <EditText
41. android:id="@+id/edt_height"
42. android:layout_width="match_parent"
43. android:layout_height="wrap_content"
44. android:inputType="numberDecimal"
45. android:lines="1"
46. android:layout_marginBottom="@dimen/activity_vertical_margin
"/>
47. <Button
48. android:id="@+id/btn_calculate"
49. android:layout_width="match_parent"
50. android:layout_height="wrap_content"
51. android:text="Hitung"
52. android:layout_marginBottom="@dimen/activity_vertical_margin
"/>
53. <TextView
54. android:id="@+id/tv_result"
55. android:layout_width="match_parent"
56. android:layout_height="wrap_content"
57. android:text="Hasil"
58. android:gravity="center"
59. android:textSize="24sp"
60. android:textStyle="bold"
61. android:layout_marginBottom="@dimen/activity_vertical_margin
"/>
62. </LinearLayout>
2. Akan muncul warning pada attribut android:text pada layout tersebut. Ini
disebabkan karena kita hardcode code string kita. Mari kita hilangkan code
warning tersebut dengan menekan alt+enter pada attribut android:text. Akan
muncul dialog seperti ini, pilihlah extract string resource.

3. Kemudian akan muncul dialog seperti dibawah ini, sesuaikan dengan nama
yang ada.

4. Fungsi extract string resource akan secara otomatis menambahkan values


dalam android:text ke dalam file res → values → strings.xml. Tambahkan juga
pada view lainnya hingga tidak ada warning lagi. Jika kita buka files
strings.xml akan seperti ini.
1. <resources>
2. <string name="app_name">BarVolume</string>
3. <string name="lebar">Lebar</string>
4. <string name="tinggi">Tinggi</string>
5. <string name="hitung">Hitung</string>
6. <string name="hasil">Hasil</string>
7. <string name="panjang">panjang</string>
8. </resources>

5. Jika terjadi error pada attribut dimens, maka kita perlu menambahkan file
dimens.xml di dalam res → values → dimens.xml. Error ini disebabkan
karena pada Android Studio 2.3 file dimens.xml sudah tidak di generate
secara otomatis ketika sebuah project dibuat. Langsung saja tambahkan
dengan cara klik kanan pada directory res. Akan muncul dialog seperti ini.
6. Kemudian isikan sesuai di bawah ini.

7. Jika file dimens.xml sudah terbuat, sesuaikan isi dari dimens.xml menjadi
seperti berikut.
1. <resources>
2. <!-- Default screen margins, per the Android Design guidelines.
-->
3. <dimen name="activity_horizontal_margin">16dp</dimen>
4. <dimen name="activity_vertical_margin">16dp</dimen>
5. </resources>

Menambahkan Kode Logika Sederhana pada MainActivity

1. Selanjutnya setelah selesai, lanjutkan dengan membuka


file MainActivity.java dan lanjutkan ngoding baris-baris dibawah ini.

1. public class MainActivity extends AppCompatActivity implements View.


OnClickListener{
2. private EditText edtWidth, edtHeight, edtLength;
3. private Button btnCalculate;
4. private TextView tvResult;
5.
6. @Override
7. protected void onCreate(Bundle savedInstanceState) {
8. super.onCreate(savedInstanceState);
9. setContentView(R.layout.activity_main);
10. edtWidth = (EditText)findViewById(R.id.edt_width);
11. edtHeight = (EditText)findViewById(R.id.edt_height);
12. edtLength = (EditText)findViewById(R.id.edt_length);
13. btnCalculate = (Button)findViewById(R.id.btn_calculate);
14. tvResult = (TextView)findViewById(R.id.tv_result);
15. btnCalculate.setOnClickListener(this);
16. }
17.
18. @Override
19. public void onClick(View v) {
20. if (v.getId() == R.id.btn_calculate){
21. String length = edtLength.getText().toString().trim();
22. String width = edtWidth.getText().toString().trim();
23. String height = edtHeight.getText().toString().trim();
24. boolean isEmptyFields = false;
25. if (TextUtils.isEmpty(length)){
26. isEmptyFields = true;
27. edtLength.setError("Field ini tidak boleh kosong");
28. }
29. if (TextUtils.isEmpty(width)){
30. isEmptyFields = true;
31. edtWidth.setError("Field ini tidak boleh kosong");
32. }
33. if (TextUtils.isEmpty(height)){
34. isEmptyFields = true;
35. edtHeight.setError("Field ini tidak boleh kosong");
36. }
37. if (!isEmptyFields) {
38. double l = Double.parseDouble(length);
39. double w = Double.parseDouble(width);
40. double h = Double.parseDouble(height);
41. double volume = l * w * h;
42. tvResult.setText(String.valueOf(volume));
43. }
44. }
45. }
46. }

Jika terdapat baris merah seperti ini :

Jangan khawatir, silakan klik keatas baris


merah tersebut dan silakan klik pada icon atau dengan tekan tombol (Alt +
Enter) lalu pilih implements method
2. Setelah sudah selesai silakan jalankan aplikasi dengan mengklik atau Run
→ Run ‘app’ dari menu bar. Kemudian ada pilihan seperti ini.

Itu tandanya adb (Android Debugger) device yang anda punya telah
terkoneksi dengan Android Studio. Jika anda tidak memiliki device silakan
gunakan emulator. Ikuti materinya
disini https://developer.android.com/studio/run/managing-avds.html.

Kami merekomendasikan anda menggunakan device Android sewaktu


develop aplikasi di Android. Selain karena akan menghemat penggunaan
memori dari device yang anda gunakan, juga akan memberikan pengalaman
yang berbeda dengan menjalankan aplikasi di device anda sendiri.
Pilih OK untuk menjalankan dan tunggu hingga proses building dan instalasi
apk aplikasi anda berjalan. Jika sudah, seharusnya hasilnya akan seperti ini.
Silakan masukan nilai panjang, lebar dan tinggi kemudian tekan tombol Hasil
dan whoilla hasilnya akan ditampilkan di obyek TextView tvHasil.
3. Selesai? Belum, masih ada yang kurang , ketika setelah menghitung luas dan
kemudian terjadi pergantian orientasi pada device maka hasil perhitungan
akan hilang. Tambahkan beberapa baris berikut pada MainActivity.java

1. private static final String STATE_HASIL = "state_hasil";


2.
3. @Override
4. protected void onSaveInstanceState(Bundle outState) {
5.
6. outState.putString(STATE_HASIL, tvResult.getText().toString());
7. super.onSaveInstanceState(outState);
8. }

Kemudian tambahkan juga beberapa baris berikut pada baris terakhir method
onCreate

9. if (savedInstanceState != null){
10. String hasil = savedInstanceState.getString(STATE_HASIL);
11. tvResult.setText(hasil);
12. }
4. Silakan jalankan aplikasi kembali kemudian coba lakukan perhitungan dan
ganti orientasi device. Jika sudah benar maka hasil perhitungan akan dijaga.

Bedah Kode

Pembahasan tentang layout xml

1. xml version="1.0" encoding="utf-8"?> =>

Baris ini mengidentifikasi bahwa file ini berformat xml.

1. xmlns:android="http://schemas.android.com/apk/res/android"
2. xmlns:tools="http://schemas.android.com/tools"

Merupakan namespace yang digunakan dalam keseluruhan file xml ini.

1. tools:context="com.dicoding.associate.barvolume.MainActivity"

Mengidentifikasi bahwa file layout xml ini berelasi dengan MainActivity.

Disini kita menggunakan beberapa komponen user interface yang


disebut View diantaranya:
TextView : Komponen View untuk menampilkan teks ke layar
EditText : Komponen View untuk memberikan input teks
Button : Komponen View untuk melakukan sebuah aksi dengan mengklik
LinearLayout : Komponen View bertipe ViewGroup yang menjadi parent dari
semua sub komponen View (Sub View) didalamnya. Komponen ini bersifat sebagai
kontainer untuk komponen lain dengan susunan secara Vertikal atau Horizontal.
Cara membaca :

1. <TextView
2. android:layout_width="match_parent"
3. android:layout_height="wrap_content"
4. android:text="Panjang"
5. android:layout_marginBottom="@dimen/activity_vertical_margin"/>

Komponen diatas adalah sebuah TextView, warna ungu menandakan namespace


yang digunakan, warna biru adalah atribut dari komponen dan warna hijau adalah
nilai dari atribut. Penjelasannya seperti dibawah ini:

match_parent: Ini berarti bahwa ukuran dimensi sebuah View disesuaikan dengan
ukuran layar secara horizontal jika pada layout_width dan vertikal jika
pada layout_height.
wrap_content : Ini berarti bahwa ukuran dimensi sebuah View disesuaikan dengan
ukuran konten didalamnya baik secara horizontal pada layout_width dan vertikal
jika pada layout_height.
@dimen/activity_vertical_margin: Value activity_vertical_margin berasal dari file
resource dimens.xml yang bisa anda lihat dengan cara menekan dan tahan
tombol ctrl (atau command) + arahkan kursor keatasnya dan kemudian klik sekali.
Penggunaan centralize resource value akan memudahkan anda sewaktu
developmen aplikasi Android. Penggunaan cara tersebut supaya tidak menulis value
yang sama berulang-ulang.
Apa itu ‘@+id/’ ?
Salah satu contoh penerapan penggunaan @+id/ sebagai berikut:

1. <Button
2. android:id="@+id/btn_calculate"
3. android:layout_width="match_parent"
4. android:layout_height="wrap_content"
5. android:text="Hitung"
6. android:layout_marginBottom="@dimen/activity_vertical_margin"/>

Penjelasannya sebagai berikut:

1. android:id="@+id/btn_calculate"

Jika kita memberikan id pada sebuah View maka kita telah memberikan identifier
untuk View tersebut agar:
Bisa kita manipulasi/dikontrol pada level logic di komponen
seperti Activity atau Fragment. ID ini akan diciptakan di file R.java kedalam bentuk
nilai hexa bertipe data Integer à public static final int btn_calculate=0x7f0b0057;
Sebagai acuan untuk penyusunan tampilan pada RelativeLayout (akan dibahas
pada modul selanjutnya).

Pembahasan tentang Logika Kode

1. public class MainActivity extends AppCompatActivity


Menandakan bahwa Kelas Java kita merupakan sebuah Activity karna inherit ke
superclass bernama AppCompatActivity

1. implements View.OnClickListener

Ini adalah listener yang kita implementasikan untuk melakukan proses event klik
pada komponen tombol (button)

Jika terdapat baris merah seperti ini :

Jangan khawatir, silakan klik ke atas baris merah tersebut dan silakan klik pada
icon atau dengan tekan tombol (Alt + Enter) lalu pilih implements method

1. private EditText edtWidth, edtHeight, edtLength;


2. private Button btnCalculate;
3. private TextView tvResult;

Deklarasi semua komponen View yang akan dimanipulasi. Kita deklarasikan secara
global agar bisa dikenal di keseluruhan bagian kelas.

1. @Override
2. protected void onCreate(Bundle savedInstanceState) {
3. super.onCreate(savedInstanceState);
4. setContentView(R.layout.activity_main);
5. edtWidth = (EditText)findViewById(R.id.edt_width);
6. edtHeight = (EditText)findViewById(R.id.edt_height);
7. edtLength = (EditText)findViewById(R.id.edt_length);
8. btnCalculate = (Button)findViewById(R.id.btn_calculate);
9. tvResult = (TextView)findViewById(R.id.tv_result);
10. btnCalculate.setOnClickListener(this);
11. }

Method onCreate() merupakan method utama pada Activity. Di sinilah kita dapat
mengatur layout xml dan semua proses inisialisasi komponen yang akan digunakan
diciptakan. Pada method ini kita casting semua komponen View yang kita telah
deklarasikan sebelumnya, agar dapat kita manipulasi.

1. setContentView(R.layout.activity_main);

Maksud baris diatas adalah bahwa kelas MainActivity akan menampilkan tampilan
yang berasal dari layout activity_main.xml

1. edtWidth = (EditText)findViewById(R.id.edt_width);

Maksud dari baris diatas adalah obyek EditText edtWidth disesuaikan (Cast)
dengan komponen EditText ber-ID edt_width di layout xml melalui
method findViewById()

1. btnCalculate.setOnClickListener(this);

Set Event Click Listener untuk obyek btnCalculate sehingga dapat melakukan
sebuah aksi ketika pengguna melakukan Klik. Keyword this menekankan pada
obyek Activity saat ini yang telah mengimplementasikan
listener OnClickListener sebelumnya.

Pembahasan saveInstanceState

1. @Override
2. protected void onSaveInstanceState(Bundle outState) {
3.
4. outState.putString(STATE_HASIL, tvResult.getText().toString());
5. super.onSaveInstanceState(outState);
6. }

Perhatikan pada method onSaveInstanceState, didalam method ini hasil


perhitungan yang ditampilkan pada tvResult dimasukkan pada bundle kemudian di
save isinya. Setelah onSaveInstanceState berhasil dijalankan maka activity akan
melakukan proses onDestroy dan menjalankan lagi OnCreate secara otomatis.

1. if (savedInstanceState != null){
2. String hasil = savedInstanceState.getString(STATE_HASIL);
3. tvResult.setText(hasil);
4. }

Pada onCreate inilah kita menggunakan nilai bundle yang telah kita simpan tadi
pada onSaveInstanceState kemudian kita isikan kembali pada tvResult.
Teori

Intent adalah mekanisme untuk melakukan sebuah action dan komunikasi antar
komponen aplikasi misal Activity, Services, dan Broadcast Receiver. Ada tiga
penggunaan umum Intent dalam aplikasi Android yaitu:

 Memindahkan satu Activity ke Activity lain dengan atau tidak membawa data.
 Menjalankan background Service misal melakukan sinkronisasi ke server dan
menjalankan proses berulang (periodic/scheduler task).
 Mengirimkan obyek broadcast ke app yang membutuhkan. Misal jika aplikasi
membutuhkan proses menjalankan sebuah background service setiap aplikasi
selesai melakukan booting. Aplikasi harus bisa menerima obyek Broadcast
yang dikirimkan oleh sistem Android untuk event booting tersebut.

Intent memiliki dua bentuk yaitu:

 Explicit Intent adalah tipe intent yang digunakan untuk menjalankan


komponen dari dalam sebuah aplikasi. Explicit intent bekerja dengan
menggunakan nama kelas yang dituju misal :
com.dicoding.activity.DetailActivity. Umumnya intent ini digunakan untuk
mengaktifkan komponen pada satu aplikasi.
 Implicit Intent adalah tipe intent yang tidak memerlukan detail nama kelas
yang ingin diaktifkan, ini memungkinkan komponen dari aplikasi lain bisa
merespon request intent yang dijalankan. Penggunaan tipe Intent ini umumnya
diperuntukan untuk menjalankan fitur/fungsi dari komponen aplikasi lain.
Contohnya ketika kita membutuhkan aplikasi kita untuk mengambil foto,
daripada kita harus membuat sendiri fungsi kamera lebih baik kita
menyerahkan proses tersebut pada aplikasi kamera bawaan dari device atau
aplikasi kamera lain yang telah terinstal sebelumnya di device atau juga jika
kita membutuhkan untuk fungsi berbagi konten, kita bisa memanfaatkan intent
untuk menampilkan mana saja aplikasi yang bisa menawarkan fungsi berbagi
(share) konten. Implementasi Intent Implicit ini akan sangat memudahkan bagi
pengembang agar tetap fokus pada proses bisnis inti dari aplikasi yang
dikembangkan.
Intents and Intent Filters
An Intent is a messaging object you can use to request an action from another app
component. Although intents facilitate communication between components in several ways,
there are three fundamental use cases:

 Starting an activity
An Activity represents a single screen in an app. You can start a new instance of
an Activity by passing an Intent to startActivity(). The Intent describes the
activity to start and carries any necessary data.
If you want to receive a result from the activity when it finishes,
call startActivityForResult(). Your activity receives the result as a
separate Intent object in your activity's onActivityResult() callback. For more
information, see the Activities guide.
 Starting a service
A Service is a component that performs operations in the background without a user
interface. With Android 5.0 (API level 21) and later, you can start a service
with JobScheduler. For more information about JobScheduler, see its API-reference
documentation.
For versions earlier than Android 5.0 (API level 21), you can start a service by using methods
of theService class. You can start a service to perform a one-time operation (such as
downloading a file) by passing an Intent to startService(). The Intent describes the
service to start and carries any necessary data.
If the service is designed with a client-server interface, you can bind to the service from
another component by passing an Intent to bindService(). For more information, see
the Services guide.
 Delivering a broadcast
A broadcast is a message that any app can receive. The system delivers various broadcasts for
system events, such as when the system boots up or the device starts charging. You can
deliver a broadcast to other apps by passing
an Intent to sendBroadcast() or sendOrderedBroadcast().

The rest of this page explains how intents work and how to use them. For related information,
see Interacting with Other Apps and Sharing Content.

Intent types

There are two types of intents:

 Explicit intents specify which application will satisfy the intent, by supplying either the
target app's package name or a fully-qualified component class name. You'll typically use an
explicit intent to start a component in your own app, because you know the class name of the
activity or service you want to start. For example, you might start a new activity within your
app in response to a user action, or start a service to download a file in the background.
 Implicit intents do not name a specific component, but instead declare a general action to
perform, which allows a component from another app to handle it. For example, if you want
to show the user a location on a map, you can use an implicit intent to request that another
capable app show a specified location on a map.

Figure 1 shows how an intent is used when starting an activity. When the Intent object
names a specific activity component explicitly, the system immediately starts that
component.

Figure 1. How an implicit intent is delivered through the system to start another activity: [1] Activity
A creates anIntent with an action description and passes it to startActivity(). [2] The Android
System searches all apps for an intent filter that matches the intent. When a match is found, [3] the system
starts the matching activity (Activity B) by invoking its onCreate() method and passing it the Intent.

When you use an implicit intent, the Android system finds the appropriate component to start
by comparing the contents of the intent to the intent filters declared in the manifest file of
other apps on the device. If the intent matches an intent filter, the system starts that
component and delivers it the Intent object. If multiple intent filters are compatible, the
system displays a dialog so the user can pick which app to use.

An intent filter is an expression in an app's manifest file that specifies the type of intents that
the component would like to receive. For instance, by declaring an intent filter for an activity,
you make it possible for other apps to directly start your activity with a certain kind of intent.
Likewise, if you do notdeclare any intent filters for an activity, then it can be started only
with an explicit intent.

Caution: To ensure that your app is secure, always use an explicit intent when starting a Service and do
not declare intent filters for your services. Using an implicit intent to start a service is a security hazard
because you can't be certain what service will respond to the intent, and the user can't see which service
starts. Beginning with Android 5.0 (API level 21), the system throws an exception if you
call bindService() with an implicit intent.
Building an intent

An Intent object carries information that the Android system uses to determine which
component to start (such as the exact component name or component category that should
receive the intent), plus information that the recipient component uses in order to properly
perform the action (such as the action to take and the data to act upon).

The primary information contained in an Intent is the following:

Component name

The name of the component to start.

This is optional, but it's the critical piece of information that makes an intent explicit,
meaning that the intent should be delivered only to the app component defined by the
component name. Without a component name, the intent is implicit and the system
decides which component should receive the intent based on the other intent
information (such as the action, data, and category—described below). If you need to
start a specific component in your app, you should specify the component name.

Note: When starting a Service, always specify the component name. Otherwise, you cannot be
certain what service will respond to the intent, and the user cannot see which service starts.

This field of the Intent is a ComponentName object, which you can specify using a
fully qualified class name of the target component, including the package name of the
app, for example,com.example.ExampleActivity. You can set the component
name with setComponent(), setClass(), setClassName(), or with
the Intent constructor.

Action

A string that specifies the generic action to perform (such as view or pick).

In the case of a broadcast intent, this is the action that took place and is being
reported. The action largely determines how the rest of the intent is structured—
particularly the information that is contained in the data and extras.

You can specify your own actions for use by intents within your app (or for use by
other apps to invoke components in your app), but you usually specify action
constants defined by the Intent class or other framework classes. Here are some
common actions for starting an activity:

ACTION_VIEW

Use this action in an intent with startActivity() when you have some
information that an activity can show to the user, such as a photo to view in a gallery
app, or an address to view in a map app.

ACTION_SEND
Also known as the share intent, you should use this in an intent
with startActivity() when you have some data that the user can share through
another app, such as an email app or social sharing app.

See the Intent class reference for more constants that define generic actions. Other
actions are defined elsewhere in the Android framework, such as in Settings for
actions that open specific screens in the system's Settings app.

You can specify the action for an intent with setAction() or with
an Intent constructor.

If you define your own actions, be sure to include your app's package name as a
prefix, as shown in the following example:

static final String ACTION_TIMETRAVEL =


"com.example.action.TIMETRAVEL";

Data

The URI (a Uri object) that references the data to be acted on and/or the MIME type
of that data. The type of data supplied is generally dictated by the intent's action. For
example, if the action is ACTION_EDIT, the data should contain the URI of the
document to edit.

When creating an intent, it's often important to specify the type of data (its MIME
type) in addition to its URI. For example, an activity that's able to display images
probably won't be able to play an audio file, even though the URI formats could be
similar. Specifying the MIME type of your data helps the Android system find the
best component to receive your intent. However, the MIME type can sometimes be
inferred from the URI—particularly when the data is a content: URI.
A content: URI indicates the data is located on the device and controlled by
a ContentProvider, which makes the data MIME type visible to the system.

To set only the data URI, call setData(). To set only the MIME type,
call setType(). If necessary, you can set both explicitly with setDataAndType().

Caution: If you want to set both the URI and MIME


type, don't call setData() and setType() because they each nullify the value of the other.
Always use setDataAndType() to set both URI and MIME type.

Category

A string containing additional information about the kind of component that should
handle the intent. Any number of category descriptions can be placed in an intent, but
most intents do not require a category. Here are some common categories:

CATEGORY_BROWSABLE

The target activity allows itself to be started by a web browser to display data
referenced by a link, such as an image or an e-mail message.
CATEGORY_LAUNCHER

The activity is the initial activity of a task and is listed in the system's application
launcher.

See the Intent class description for the full list of categories.

You can specify a category with addCategory().

These properties listed above (component name, action, data, and category) represent the
defining characteristics of an intent. By reading these properties, the Android system is able
to resolve which app component it should start. However, an intent can carry additional
information that does not affect how it is resolved to an app component. An intent can also
supply the following information:

Extras

Key-value pairs that carry additional information required to accomplish the requested
action. Just as some actions use particular kinds of data URIs, some actions also use
particular extras.

You can add extra data with various putExtra() methods, each accepting two
parameters: the key name and the value. You can also create a Bundle object with all
the extra data, then insert the Bundle in the Intent with putExtras().

For example, when creating an intent to send an email with ACTION_SEND, you can
specify the to recipient with the EXTRA_EMAIL key, and specify the subject with
the EXTRA_SUBJECT key.

The Intent class specifies many EXTRA_* constants for standardized data types. If
you need to declare your own extra keys (for intents that your app receives), be sure
to include your app's package name as a prefix, as shown in the following example:

static final String EXTRA_GIGAWATTS =


"com.example.EXTRA_GIGAWATTS";

Caution: Do not use Parcelable or Serializable data when sending an intent that you
expect another app to receive. If an app attempts to access data in a Bundle object but does not
have access to the parceled or serialized class, the system raises a RuntimeException.

Flags

Flags are defined in the Intent class that function as metadata for the intent. The
flags may instruct the Android system how to launch an activity (for example,
which task the activity should belong to) and how to treat it after it's launched (for
example, whether it belongs in the list of recent activities).

For more information, see the setFlags() method.


Example explicit intent
An explicit intent is one that you use to launch a specific app component, such as a particular
activity or service in your app. To create an explicit intent, define the component name for
the Intent object—all other intent properties are optional.

For example, if you built a service in your app, named DownloadService, designed to
download a file from the web, you can start it with the following code:

// Executed in an Activity, so 'this' is the Context


// The fileUrl is a string URL, such as
"http://www.example.com/image.png"
Intent downloadIntent = new Intent(this, DownloadService.class);
downloadIntent.setData(Uri.parse(fileUrl));
startService(downloadIntent);

The Intent(Context, Class) constructor supplies the app Context and the component
a Class object. As such, this intent explicitly starts the DownloadService class in the app.

For more information about building and starting a service, see the Services guide.

Example implicit intent


An implicit intent specifies an action that can invoke any app on the device able to perform
the action. Using an implicit intent is useful when your app cannot perform the action, but
other apps probably can and you'd like the user to pick which app to use.

For example, if you have content that you want the user to share with other people, create an
intent with the ACTION_SEND action and add extras that specify the content to share. When
you call startActivity() with that intent, the user can pick an app through which to share
the content.

Caution: It's possible that a user won't have any apps that handle the implicit intent you send
to startActivity(). Or, an app may be inaccessible because of profile restrictions or settings put into
place by an administrator. If that happens, the call fails and your app crashes. To verify that an activity will
receive the intent, call resolveActivity()on your Intent object. If the result is non-null, there is at
least one app that can handle the intent and it's safe to callstartActivity(). If the result is null, do not
use the intent and, if possible, you should disable the feature that issues the intent. The following example
shows how to verify that the intent resolves to an activity. This example doesn't use a URI, but the intent's
data type is declared to specify the content carried by the extras.

// Create the text message with a string


Intent sendIntent = new Intent();
sendIntent.setAction(Intent.ACTION_SEND);
sendIntent.putExtra(Intent.EXTRA_TEXT, textMessage);
sendIntent.setType("text/plain");

// Verify that the intent will resolve to an activity


if (sendIntent.resolveActivity(getPackageManager()) != null) {
startActivity(sendIntent);
}

When startActivity() is called, the system examines all of the installed apps to
determine which ones can handle this kind of intent (an intent with the ACTION_SEND action
and that carries "text/plain" data). If there's only one app that can handle it, that app opens
immediately and is given the intent. If multiple activities accept the intent, the system
displays a dialog such as the one shown in Figure 2, so the user can pick which app to use.

More information about launching other apps is also provided in Sending the User to Another
App.

Figure 2. A chooser dialog.


Forcing an app chooser
When there is more than one app that responds to your implicit intent, the user can select
which app to use and make that app the default choice for the action. The ability to select a
default is helpful when performing an action for which the user probably wants to use the
same app every time, such as when opening a web page (users often prefer just one web
browser).

However, if multiple apps can respond to the intent and the user might want to use a different
app each time, you should explicitly show a chooser dialog. The chooser dialog asks the user
to select which app to use for the action (the user cannot select a default app for the action).
For example, when your app performs "share" with the ACTION_SEND action, users may
want to share using a different app depending on their current situation, so you should always
use the chooser dialog, as shown in Figure 2.

To show the chooser, create an Intent using createChooser() and pass it


to startActivity(), as shown in the following example. This example displays a dialog
with a list of apps that respond to the intent passed to the createChooser() method and
uses the supplied text as the dialog title.

Intent sendIntent = new Intent(Intent.ACTION_SEND);


...

// Always use string resources for UI text.


// This says something like "Share this photo with"
String title = getResources().getString(R.string.chooser_title);
// Create intent to show the chooser dialog
Intent chooser = Intent.createChooser(sendIntent, title);

// Verify the original intent will resolve to at least one activity


if (sendIntent.resolveActivity(getPackageManager()) != null) {
startActivity(chooser);
}

Receiving an implicit intent

To advertise which implicit intents your app can receive, declare one or more intent filters for
each of your app components with an <intent-filter> element in your manifest file.
Each intent filter specifies the type of intents it accepts based on the intent's action, data, and
category. The system delivers an implicit intent to your app component only if the intent can
pass through one of your intent filters.

Note: An explicit intent is always delivered to its target, regardless of any intent filters the component
declares.

An app component should declare separate filters for each unique job it can do. For example,
one activity in an image gallery app may have two filters: one filter to view an image, and
another filter to edit an image. When the activity starts, it inspects the Intent and decides
how to behave based on the information in the Intent (such as to show the editor controls or
not).

Each intent filter is defined by an <intent-filter> element in the app's manifest file,
nested in the corresponding app component (such as an <activity> element). Inside
the <intent-filter>, you can specify the type of intents to accept using one or more of
these three elements:

<action>

Declares the intent action accepted, in the name attribute. The value must be the
literal string value of an action, not the class constant.

<data>

Declares the type of data accepted, using one or more attributes that specify various
aspects of the data URI (scheme, host, port, path) and MIME type.

<category>

Declares the intent category accepted, in the name attribute. The value must be the
literal string value of an action, not the class constant.

Note: To receive implicit intents, you must include the CATEGORY_DEFAULT category in the
intent filter. The methods startActivity() and startActivityForResult() treat all
intents as if they declared the CATEGORY_DEFAULT category. If you do not declare this category
in your intent filter, no implicit intents will resolve to your activity.

For example, here's an activity declaration with an intent filter to receive


an ACTION_SEND intent when the data type is text:

<activity android:name="ShareActivity">
<intent-filter>
<action android:name="android.intent.action.SEND"/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:mimeType="text/plain"/>
</intent-filter>
</activity>

You can create a filter that includes more than one instance of <action>, <data>,
or <category>. If you do, you need to be certain that the component can handle any and all
combinations of those filter elements.

When you want to handle multiple kinds of intents, but only in specific combinations of
action, data, and category type, then you need to create multiple intent filters.
Restricting access to components

Using an intent filter is not a secure way to prevent other apps from starting your
components. Although intent filters restrict a component to respond to only certain kinds of
implicit intents, another app can potentially start your app component by using an explicit
intent if the developer determines your component names. If it's important that only your own
app is able to start one of your components, do not declare intent filters in your manifest.
Instead, set the exported attribute to "false" for that component.

An implicit intent is tested against a filter by comparing the intent to each of the three
elements. To be delivered to the component, the intent must pass all three tests. If it fails to
match even one of them, the Android system won't deliver the intent to the component.
However, because a component may have multiple intent filters, an intent that does not pass
through one of a component's filters might make it through on another filter. More
information about how the system resolves intents is provided in the section below
about Intent Resolution.

Caution: To avoid inadvertently running a different app's Service, always use an explicit intent to start
your own service and do not declare intent filters for your service.
Note: For all activities, you must declare your intent filters in the manifest file. However, filters for
broadcast receivers can be registered dynamically by calling registerReceiver(). You can then
unregister the receiver with unregisterReceiver(). Doing so allows your app to listen for specific
broadcasts during only a specified period of time while your app is running.

Example filters
To demonstrate some of the intent filter behaviors, here is an example from the manifest file
of a social-sharing app:

<activity android:name="MainActivity">
<!-- This activity is the main entry, should appear in app launcher
-->
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>

<activity android:name="ShareActivity">
<!-- This activity handles "SEND" actions with text data -->
<intent-filter>
<action android:name="android.intent.action.SEND"/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:mimeType="text/plain"/>
</intent-filter>
<!-- This activity also handles "SEND" and "SEND_MULTIPLE" with
media data -->
<intent-filter>
<action android:name="android.intent.action.SEND"/>
<action android:name="android.intent.action.SEND_MULTIPLE"/>
<category android:name="android.intent.category.DEFAULT"/>
<data
android:mimeType="application/vnd.google.panorama360+jpg"/>
<data android:mimeType="image/*"/>
<data android:mimeType="video/*"/>
</intent-filter>
</activity>

The first activity, MainActivity, is the app's main entry point—the activity that opens
when the user initially launches the app with the launcher icon:

 The ACTION_MAIN action indicates this is the main entry point and does not expect any
intent data.
 The CATEGORY_LAUNCHER category indicates that this activity's icon should be placed in the
system's app launcher. If the <activity> element does not specify an icon with icon, then
the system uses the icon from the <application> element.

These two must be paired together in order for the activity to appear in the app launcher.

The second activity, ShareActivity, is intended to facilitate sharing text and media
content. Although users might enter this activity by navigating to it from MainActivity,
they can also enter ShareActivity directly from another app that issues an implicit intent
matching one of the two intent filters.

Note: The MIME type, application/vnd.google.panorama360+jpg, is a special data type that


specifies panoramic photos, which you can handle with the Google panorama APIs.

Using a pending intent

A PendingIntent object is a wrapper around an Intent object. The primary purpose of


a PendingIntent is to grant permission to a foreign application to use the
contained Intent as if it were executed from your app's own process.

Major use cases for a pending intent include the following:

 Declaring an intent to be executed when the user performs an action with


your Notification (the Android system's NotificationManager executes the Intent).
 Declaring an intent to be executed when the user performs an action with your App
Widget (the Home screen app executes the Intent).
 Declaring an intent to be executed at a specified future time (the Android
system's AlarmManager executes the Intent).
Just as each Intent object is designed to be handled by a specific type of app component
(either an Activity, a Service, or a BroadcastReceiver), so too must
a PendingIntent be created with the same consideration. When using a pending intent,
your app doesn't execute the intent with a call such as startActivity(). Instead, you must
declare the intended component type when you create the PendingIntent by calling the
respective creator method:

 PendingIntent.getActivity() for an Intent that starts an Activity.


 PendingIntent.getService() for an Intent that starts a Service.
 PendingIntent.getBroadcast() for a Intent that starts an BroadcastReceiver.

Unless your app is receiving pending intents from other apps, the above methods to create
a PendingIntent are probably the only PendingIntent methods you'll ever need.

Each method takes the current app Context, the Intent you want to wrap, and one or more
flags that specify how the intent should be used (such as whether the intent can be used more
than once).

For more information about using pending intents, see the documentation for each of the
respective use cases, such as in the Notifications and App Widgets API guides.

Intent resolution

When the system receives an implicit intent to start an activity, it searches for the best
activity for the intent by comparing it to intent filters based on three aspects:

 Action.
 Data (both URI and data type).
 Category.

The following sections describe how intents are matched to the appropriate components
according to the intent filter declaration in an app's manifest file.

Action test
To specify accepted intent actions, an intent filter can declare zero or
more <action> elements, as shown in the following example:

<intent-filter>
<action android:name="android.intent.action.EDIT" />
<action android:name="android.intent.action.VIEW" />
...
</intent-filter>
To pass this filter, the action specified in the Intent must match one of the actions listed in
the filter.

If the filter does not list any actions, there is nothing for an intent to match, so all intents fail
the test. However, if an Intent does not specify an action, it passes the test as long as the
filter contains at least one action.

Category test
To specify accepted intent categories, an intent filter can declare zero or
more <category> elements, as shown in the following example:

<intent-filter>
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
...
</intent-filter>

For an intent to pass the category test, every category in the Intent must match a category
in the filter. The reverse is not necessary—the intent filter may declare more categories than
are specified in the Intent and theIntent still passes. Therefore, an intent with no
categories always passes this test, regardless of what categories are declared in the filter.

Note: Android automatically applies the CATEGORY_DEFAULT category to all implicit intents passed
to startActivity() and startActivityForResult(). If you want your activity to receive implicit
intents, it must include a category for "android.intent.category.DEFAULT" in its intent filters, as
shown in the previous <intent-filter> example.

Data test
To specify accepted intent data, an intent filter can declare zero or more <data> elements, as
shown in the following example:

<intent-filter>
<data android:mimeType="video/mpeg" android:scheme="http" ... />
<data android:mimeType="audio/mpeg" android:scheme="http" ... />
...
</intent-filter>

Each <data> element can specify a URI structure and a data type (MIME media type). Each
part of the URI is a separate attribute: scheme, host, port, and path:

<scheme>://<host>:<port>/<path>

The following example shows possible values for these attributes:

content://com.example.project:200/folder/subfolder/etc
In this URI, the scheme is content, the host is com.example.project, the port is 200,
and the path is folder/subfolder/etc.

Each of these attributes is optional in a <data> element, but there are linear dependencies:

 If a scheme is not specified, the host is ignored.


 If a host is not specified, the port is ignored.
 If both the scheme and host are not specified, the path is ignored.

When the URI in an intent is compared to a URI specification in a filter, it's compared only to
the parts of the URI included in the filter. For example:

 If a filter specifies only a scheme, all URIs with that scheme match the filter.
 If a filter specifies a scheme and an authority but no path, all URIs with the same scheme and
authority pass the filter, regardless of their paths.
 If a filter specifies a scheme, an authority, and a path, only URIs with the same scheme,
authority, and path pass the filter.
Note: A path specification can contain a wildcard asterisk (*) to require only a partial match of the path
name.

The data test compares both the URI and the MIME type in the intent to a URI and MIME
type specified in the filter. The rules are as follows:

1. An intent that contains neither a URI nor a MIME type passes the test only if the filter does
not specify any URIs or MIME types.
2. An intent that contains a URI but no MIME type (neither explicit nor inferable from the URI)
passes the test only if its URI matches the filter's URI format and the filter likewise does not
specify a MIME type.
3. An intent that contains a MIME type but not a URI passes the test only if the filter lists the
same MIME type and does not specify a URI format.
4. An intent that contains both a URI and a MIME type (either explicit or inferable from the
URI) passes the MIME type part of the test only if that type matches a type listed in the filter.
It passes the URI part of the test either if its URI matches a URI in the filter or if it has
a content: or file: URI and the filter does not specify a URI. In other words, a
component is presumed to support content: and file: data if its filter lists only a MIME
type.

This last rule, rule (d), reflects the expectation that components are able to get local data from
a file or content provider. Therefore, their filters can list just a data type and don't need to
explicitly name the content: and file: schemes. The following example shows a typical
case in which a <data> element tells Android that the component can get image data from a
content provider and display it:

<intent-filter>
<data android:mimeType="image/*" />
...
</intent-filter>
Filters that specify a data type but not a URI are perhaps the most common because most
available data is dispensed by content providers.

Another common configuration is a filter with a scheme and a data type. For example,
a <data> element like the following tells Android that the component can retrieve video data
from the network in order to perform the action:

<intent-filter>
<data android:scheme="http" android:type="video/*" />
...
</intent-filter>

Intent matching
Intents are matched against intent filters not only to discover a target component to activate,
but also to discover something about the set of components on the device. For example, the
Home app populates the app launcher by finding all the activities with intent filters that
specify the ACTION_MAIN action and CATEGORY_LAUNCHERcategory. A match is only
successful if the actions and categories in the Intent match against the filter, as described in
the documentation for the IntentFilter class.

Your application can use intent matching in a manner similar to what the Home app does.
The PackageManagerhas a set of query...() methods that return all components that can
accept a particular intent and a similar series of resolve...() methods that determine the
best component to respond to an intent. For example,queryIntentActivities() returns
a list of all activities that can perform the intent passed as an argument,
and queryIntentServices() returns a similar list of services. Neither method activates
the components; they just list the ones that can respond. There's a similar
method, queryBroadcastReceivers(), for broadcast receivers.
Tujuan

Codelab ini menitik beratkan pada implementasi Intent untuk melakukan perpindahan
dari Activity ke Activity dengan atau tidak membawa data. Beberapa bagian dari code
lab ini akan menjawab beberapa pertanyaan umum dalam pengembangan aplikasi
Android sebagai berikut:

 Bagaimana berpindah dari satu Activity ke Activity lain?


 Bagaimana berpindah dari satu Activity ke Activity lain dengan membawa data?
o Single Value dari sebuah variable.
o Obyek Model Plain Old Java Object (POJO).
 Menjalankan komponen di aplikasi lain untuk keperluan membuka browser
atau melakukan pemanggilan melalui aplikasi telepon bawaan?
 Mengirimkan hasil nilai balik melalui Intent

Logika Dasar

Berpindah dari satu Activity ke Activity lain dengan membawa data. Activity asal
akan mengirimkan data melalui Intent dan Activity tujuan akan menerima data yang
dikirimkan.

1. Buat Project baru di Android Studio dengan kriteria sebagai berikut:


o Nama Project : MyIntentApp
o Target & Minimum Target SDK : Phone and Tablet; Api level 15
o Tipe Activity : Empty Activity
o Activity Name : MainActivity
2. Selanjutnya kita akan membangun User Interface menjadi seperti ini:

3. Kita akan memiliki 5 tombol dengan fungsi yang berbeda-beda dan 1


buah TextView untuk menampilkan data yang berasal dari Intent. Baik, kita
akan mulai selangkah demi selangkah dimulai dari tombol yang paling atas.
Kondisikan activity_main.xml menjadi seperti ini:
1. <?xml version="1.0" encoding="utf-8"?>
2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/andro
id"
3. xmlns:tools="http://schemas.android.com/tools"
4. android:layout_width="match_parent"
5. android:layout_height="match_parent"
6. android:paddingBottom="@dimen/activity_vertical_margin"
7. android:paddingLeft="@dimen/activity_horizontal_margin"
8. android:paddingRight="@dimen/activity_horizontal_margin"
9. android:paddingTop="@dimen/activity_vertical_margin"
10. android:orientation="vertical"
11. tools:context="com.dicoding.associate.myintentapp.MainActivity">
12. <Button
13. android:id="@+id/btn_move_activity"
14. android:layout_width="match_parent"
15. android:layout_height="wrap_content"
16. android:text="Pindah Activity"
17. android:layout_marginBottom="@dimen/activity_vertical_margin"/
>
18. </LinearLayout>

Jangan lupa untuk menambahkan file dimens.xml secara manual di dalam res
→ values. Dan isikan file dimens.xml seperti berikut

19. <resources>
20. <!-- Default screen margins, per the Android Design guidelines. -
->
21. <dimen name="activity_horizontal_margin">16dp</dimen>
22. <dimen name="activity_vertical_margin">16dp</dimen>
23. </resources>
4. Lalu untuk MainActivity.java tambahkan beberapa baris seperti ini.

0. public class MainActivity extends AppCompatActivity implements View.O


nClickListener{
1. private Button btnMoveActivity;
2. @Override
3. protected void onCreate(Bundle savedInstanceState) {
4. super.onCreate(savedInstanceState);
5. setContentView(R.layout.activity_main);
6.
7. btnMoveActivity = (Button)findViewById(R.id.btn_move_activity)
;
8. btnMoveActivity.setOnClickListener(this);
9. }
10. @Override
11. public void onClick(View v) {
12. switch (v.getId()){
13. case R.id.btn_move_activity:
14. break;
15. }
16. }
17. }
5. Button btnMoveActivity akan memiliki fungsi untuk berpindah Activity ke
Activity lain. Sekarang kita buat Activity baru dengan cara sebagai berikut:
Klik kanan di package utama
aplikasi com.dicoding.associate.myintentapp → New → Activity → Empty
Activity.
Lalu isikan MoveActivity pada dialog. Ketika sudah klik finish.
6. Untuk menandakan perpindahan Activity berhasil, silakan tambahkan satu
buat TextView dan kondisikan activity_move.xml menjadi seperti berikut.

0. <?xml version="1.0" encoding="utf-8"?>


1. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/an
droid"
2. xmlns:tools="http://schemas.android.com/tools"
3. android:layout_width="match_parent"
4. android:layout_height="match_parent"
5. android:paddingBottom="@dimen/activity_vertical_margin"
6. android:paddingLeft="@dimen/activity_horizontal_margin"
7. android:paddingRight="@dimen/activity_horizontal_margin"
8. android:paddingTop="@dimen/activity_vertical_margin"
9. tools:context="com.dicoding.associate.myintentapp.MoveActivity">
10. <TextView
11. android:layout_width="match_parent"
12. android:layout_height="wrap_content"
13. android:text="Ini MoveActivity"/>
14. </RelativeLayout>
7. Setelah Activity tujuan sudah berhasil diciptakan, sekarang saatnya
menambahkan sebuah Intent pada
method onClick() di MainActivity.java menjadi sebagai berikut.

0. public class MainActivity extends AppCompatActivity implements View.


OnClickListener{
1. private Button btnMoveActivity;
2. @Override
3. protected void onCreate(Bundle savedInstanceState) {
4. super.onCreate(savedInstanceState);
5. setContentView(R.layout.activity_main);
6. btnMoveActivity = (Button)findViewById(R.id.btn_move_activity
);
7. btnMoveActivity.setOnClickListener(this);
8. }
9. @Override
10. public void onClick(View v) {
11. switch (v.getId()){
12. case R.id.btn_move_activity:
13. Intent moveIntent = new Intent(MainActivity.this, Mov
eActivity.class);
14. startActivity(moveIntent);
15. break;
16. }
17. }
18. }

Selesai! Langkah pertama untuk memindahkan satu Activity ke Activity lain sudah
selesai, sekarang silakan jalankan aplikasi anda dengan mengklik tombol pada
menu bar. Seharusnya sekarang anda sudah bisa memindahkan Activity dengan
mengklik tombol ‘Pindah Activity’.
Bedah Kode

Kita telah belajar bagaimana membuat sebuah Activity baru, di materi sebelumnya
syarat sebuah Activity harus terdaftar pada file AndroidManifest.xml dan semenjak
menggunakan Android Studio proses pendaftaran Activity ke
file AndroidManifest.xml dilakukan secara otomatis tidak manual seperti di era
eclipse.

1. <?xml version="1.0" encoding="utf-8"?>


2. <manifest xmlns:android="http://schemas.android.com/apk/res/android"
3. package="com.dicoding.associate.myintentapp">
4. <application
5. android:allowBackup="true"
6. android:icon="@mipmap/ic_launcher"
7. android:label="@string/app_name"
8. android:supportsRtl="true"
9. android:theme="@style/AppTheme">
10. <activity android:name=".MainActivity">
11. <intent-filter>
12. <action android:name="android.intent.action.MAIN" />
13. <category android:name="android.intent.category.LAUNCHER" />
14. </intent-filter>
15. </activity>
16. <activity android:name=".MoveActivity"></activity>
17. </application>
18. </manifest>

Perhatikan bahwa MoveActivity sudah teregistrasi di AndroidManifest.xml dan


sekarang sudah aman jika kita melakukan perpindahan Activity dari MainActivity ke
MoveActivity. Umumnya, jika kita lupa meregistrasikan Activity baru ke dalam
file AndroidManifest.xml akan terjadi error seperti ini
android.content.ActivityNotFoundException:Unable to find explicit activity class
Ok, saya tahu kalian menanyakan maksud dari baris ini.

1. <intent-filter>
2. <action android:name="android.intent.action.MAIN" />
3. <category android:name="android.intent.category.LAUNCHER" />
4. </intent-filter>

Begini, Intent-filter merupakan mekanisme untuk menentukan bagaimana sebuah


Activity dijalankan oleh Android Runtime (ART) atau Dalvik Virtual Machine (DVM).

1. <action android:name="android.intent.action.MAIN" />

Baris diatas bermakna bahwa MainActivity memiliki Intent Action utama dari
keseluruhan Activity yang ada di sebuah Aplikasi. Sedangkan

1. <category android:name="android.intent.category.LAUNCHER" />


Bermakna, bahwa MainActivity akan dikategorikan sebagai Activity Launcher yang
pertama kali diluncurkan ketika pengguna mengklik icon aplikasi pada handset
Android anda.
Selanjutnya,

1. Intent moveIntent = new Intent(MainActivity.this, MoveActivity.class);

Kita membuat sebuah obyek Intent dengan cara seperti diatas dengan memberikan
Kelas Activity Asal (MainActivity.this) dan Kelas Activity
tujuan (MoveActivity.class) pada kontruktor kelas Intent (constructor).

Kelas asal selalu ditekankan dengan .this yang menandakan obyek kelas saat ini dan
kelas tujuan selalu ditekankan .class.
Jika kita membiarkan code assistant dari Android Studio, maka akan tampil
rekomendasi (code hint) sebagai berikut:

Pada konteks diatas kita memilih Context packageContext, Class<?> cls sebagai
inputan untuk nilai kontruktor Intent.

startActivity(moveIntent); => method disamping akan menjalankan Activity baru


tanpa membawa data berdasarkan obyek Intent yang diinputkan pada case ini adalah
obyek moveIntent yang akan menjalankan MoveActivity.

Setelah kita telah berhasil memindahkan satu Activity ke Activity lain dengan
tidak membawa data. Nah, pada bagian selanjutnya kita akan membuat sebuah
Intent yang didalamnya akan membawa data ke Activity tujuan.
elanjutnya adalah kita akan membuat sebuah Intent yang didalamnya akan membawa
data ke Activity tujuan. Siap?

1. Ayo buka activity_main.xml lagi dan tambahkan satu tombol lagi dibawah
tombol sebelumnya sehingga kode activity_main.xml kita menjadi seperti ini.

1. <?xml version="1.0" encoding="utf-8"?>


2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/andro
id"
3. xmlns:tools="http://schemas.android.com/tools"
4. android:layout_width="match_parent"
5. android:layout_height="match_parent"
6. android:paddingBottom="@dimen/activity_vertical_margin"
7. android:paddingLeft="@dimen/activity_horizontal_margin"
8. android:paddingRight="@dimen/activity_horizontal_margin"
9. android:paddingTop="@dimen/activity_vertical_margin"
10. android:orientation="vertical"
11. tools:context="com.dicoding.associate.myintentapp.MainActivity">
12. <Button
13. android:id="@+id/btn_move_activity"
14. android:layout_width="match_parent"
15. android:layout_height="wrap_content"
16. android:text="Pindah Activity"
17. android:layout_marginBottom="@dimen/activity_vertical_margin"/
>
18. <Button
19. android:id="@+id/btn_move_activity_data"
20. android:layout_width="match_parent"
21. android:layout_height="wrap_content"
22. android:text="Pindah Activity dengan Data"
23. android:layout_marginBottom="@dimen/activity_vertical_margin"/
>
24. </LinearLayout>

Tambahkan kembali dimens.xml secara manual di dalam res → values. Dan


isikan filenya menjadi seperti berikut.

25. <resources>
26. <!-- Default screen margins, per the Android Design guidelines. -
->
27. <dimen name="activity_horizontal_margin">16dp</dimen>
28. <dimen name="activity_vertical_margin">16dp</dimen>
29. </resources>
2. Setelah selesai dengan penambahan pada file activity_main.xml, maka
dilanjutkan dengan menambahkan beberapa baris berikut
di MainActivity.java (yang ditebalkan).

1. public class MainActivity extends AppCompatActivity implements View.O


nClickListener{
2. private Button btnMoveActivity;
3. private Button btnMoveWithDataActivity;
4. @Override
5. protected void onCreate(Bundle savedInstanceState) {
6. super.onCreate(savedInstanceState);
7. setContentView(R.layout.activity_main);
8. btnMoveActivity = (Button)findViewById(R.id.btn_move_activity)
;
9. btnMoveActivity.setOnClickListener(this);
10. btnMoveWithDataActivity = (Button)findViewById(R.id.btn_move_a
ctivity_data);
11. btnMoveWithDataActivity.setOnClickListener(this);
12. }
13. @Override
14. public void onClick(View v) {
15. switch (v.getId()){
16. case R.id.btn_move_activity:
17. Intent moveIntent = new Intent(MainActivity.this, Move
Activity.class);
18. startActivity(moveIntent);
19. break;
20. case R.id.btn_move_activity_data:
21. break;
22. }
23. }
24. }
3. Selanjutnya, buat Activity baru lagi seperti cara sebelumnya dan namakan
Activity-nya dengan MoveWithDataActivity. Lalu,
pada activity_move_with_data.xml kita tambahkan sebuah TextView ber-ID
untuk menampilkan data yang dikirimkan dari Activity asal.

1. <?xml version="1.0" encoding="utf-8"?>


2. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/and
roid"
3. xmlns:tools="http://schemas.android.com/tools"
4. android:layout_width="match_parent"
5. android:layout_height="match_parent"
6. android:paddingBottom="@dimen/activity_vertical_margin"
7. android:paddingLeft="@dimen/activity_horizontal_margin"
8. android:paddingRight="@dimen/activity_horizontal_margin"
9. android:paddingTop="@dimen/activity_vertical_margin"
10. tools:context="com.dicoding.associate.myintentapp.MoveWithDataActi
vity">
11. <TextView
12. android:id="@+id/tv_data_received"
13. android:layout_width="match_parent"
14. android:layout_height="wrap_content"
15. android:text="Data Received"/>
16. </RelativeLayout>
4. Selanjutnya pada MoveWithDataActivity.java kita kondisikan menjadi seperti
berikut:

1. public class MoveWithDataActivity extends AppCompatActivity {


2. public static String EXTRA_AGE = "extra_age";
3. public static String EXTRA_NAME = "extra_name";
4. private TextView tvDataReceived;
5. @Override
6. protected void onCreate(Bundle savedInstanceState) {
7. super.onCreate(savedInstanceState);
8. setContentView(R.layout.activity_move_with_data);
9. tvDataReceived = (TextView)findViewById(R.id.tv_data_received)
;
10. String name = getIntent().getStringExtra(EXTRA_NAME);
11. int age = getIntent().getIntExtra(EXTRA_AGE, 0);
12. String text = "Name : "+name+", Your Age : "+age;
13. tvDataReceived.setText(text);
14. }
15. }
5. Dan sekarang saatnya kita menambahkan obyek Intent
pada MainActivity.java seperti baris yang ditebalkan.

1. public class MainActivity extends AppCompatActivity implements View.O


nClickListener{
2. private Button btnMoveActivity;
3. private Button btnMoveWithDataActivity;
4. @Override
5. protected void onCreate(Bundle savedInstanceState) {
6. super.onCreate(savedInstanceState);
7. setContentView(R.layout.activity_main);
8. btnMoveActivity = (Button)findViewById(R.id.btn_move_activity)
;
9. btnMoveActivity.setOnClickListener(this);
10. btnMoveWithDataActivity = (Button)findViewById(R.id.btn_move_a
ctivity_data);
11. btnMoveWithDataActivity.setOnClickListener(this);
12. }
13. @Override
14. public void onClick(View v) {
15. switch (v.getId()){
16. case R.id.btn_move_activity:
17. Intent moveIntent = new Intent(MainActivity.this, Move
Activity.class);
18. startActivity(moveIntent);
19. break;
20. case R.id.btn_move_activity_data:
21. Intent moveWithDataIntent = new Intent(MainActivity.th
is, MoveWithDataActivity.class);
22. moveWithDataIntent.putExtra(MoveWithDataActivity.EXTRA
_NAME, "DicodingAcademy Boy");
23. moveWithDataIntent.putExtra(MoveWithDataActivity.EXTRA
_AGE, 5);
24. startActivity(moveWithDataIntent);
25. break;
26. }
27. }
28. }
6. Sekarang, silakan jalankan aplikasi andalagi dan coba klik pada tombol ‘Pindah
Activity dengan Data’ dan Selamat! Seharusnya andasudah bisa memindahkan
satu Activity ke Activity lain dengan membawa data.
Bedah Kode

Pada bagian sebelumnya anda sudah mempelajari bagaimana memindahkan satu


Activity ke Activity lain dengan membawa data. Dan itu sangat penting karena ketika
kita mengembangkan sebuah aplikasi Android yang kompleks maka akan banyak
sekali Activity yang terlibat dan perpindahan Activity dengan data akan menjadi sangat
krusial dalam memaksimalkan konten yang ada dengan experience yang diberikan
oleh aplikasi kepada pengguna.

1. Intent moveWithDataIntent = new Intent(MainActivity.this, MoveWithDataActiv


ity.class);
2. moveWithDataIntent.putExtra(MoveWithDataActivity.EXTRA_NAME, "DicodingAcade
my Boy");
3. moveWithDataIntent.putExtra(MoveWithDataActivity.EXTRA_AGE, 5);
4. startActivity(moveWithDataIntent);

Perbedaan mendasar antara memindahkan Activity dengan membawa data dan tidak
adalah dengan menempatkan data yang akan dikirim ke Activity tujuan pada baris ini.

1. moveWithDataIntent.putExtra(MoveWithDataActivity.EXTRA_NAME, "DicodingAcade
my Boy");
2. moveWithDataIntent.putExtra(MoveWithDataActivity.EXTRA_AGE, 5);

Kita memanfaatkan method putExtra() untuk mengirimkan data bersamaan dengan


obyek Intent. Sedangkan method putExtra() itu sendiri merupakan method yang
menampung pasangan Key-Value dan memiliki beberapa pilihan tipe input seperti
berikut :

Hampir semua tipe data untuk input value disupport oleh method putExtra().

1. moveWithDataIntent.putExtra(MoveWithDataActivity.EXTRA_NAME,"DicodingAcadem
y Boy");

⇒ Name : MoveWithDataActivity.EXTRA_NAME dimana EXTRA_NAME adalah


variabel static bertipe data String dan bernilai “extra_name” pada
MoveWithDataActivity.java. penentuan nilai untuk Key parameter untuk Intent adalah
bebas disini kami merekomendasikan format terbaik yang biasa diimplementasikan.
⇒ Value : DicodingAcademy Boy.
Disini kita akan mengirimkan data bertipe String ke MoveWithDataActivity dan
kemudian pada MoveWithDataActivity akan dilakukan proses pengambilan nilai data
berdasarkan Key yang dikirimkan dengan menggunakan method
getIntent().getStringExtra(key). Implementasinya sebagai berikut:

1. String name = getIntent().getStringExtra(EXTRA_NAME);

Catatan : Key yang dikirimkan via putExtra() harus sama dengan Key sewaktu
mengambil nilai dari data yang dikirimkan melalui getStringExtra()
Dalam konteks diatas key yang dikirimkan dan key sewaktu mengambil nilai data
adalah sama yaitu EXTRA_NAME (yang bernilai “extra_name”) dan nilai dari data
yang dikirimkan via Intent disimpan kedalam variable name bertipe data String.
Begitu juga dengan,

1. int age = getIntent().getIntExtra(EXTRA_AGE, 0);

Nilai dari variabel age yang bertipe data integer berasal


dari getIntent().getIntExtra(Key, nilai default). Key yang digunakan untuk
mengirimkan dan mengambil data adalah EXTRA_AGE (yang bernilai “extra_age”)

Sekali lagi selamat! Anda telah mempelajari dua Intent explicit dengan atau tidak
membawa data. Sebelumnya, mengirimkan data bernilai tunggal dari satu Activity ke
Activity lain adalah hal yang mudah. Bernilai tunggal karena data yang dikirimkan
berasal dari satu tipe data. Misal diatas, pengiriman nilai data name dan age dilakukan
secara sendiri-sendiri, yang satu bertipe data String dan yang lainnya bertipe data
integer. Sekarang pertanyaanya bagaimana anda bisa mengirimkan data dalam
bentuk Plain Old Java Object (POJO) dari satu Activity ke Activity lain melalui Intent?
Caranya adalah dengan mengkonversi Object POJO yang anda miliki ke dalam
bentuk parcelable object.

Pada kelas ini tidak akan dijelaskan tentang parcelable object. Untuk materi
yang lebih lengkap dan komprehensif mengenai parcelable object bisa
langsung daftar kelas Menjadi Android Developer Expert.
aik, anda sudah belajar bagaimana menggunakan Intent dengan tipe eksplisit,
sekarang saat-nya anda melanjutkan ke Intent dengan tipe implicit.

1. Buka kembali activity_main.xml tambahkan satu tombol lagi sebagai berikut :

2. <Button
3. android:id="@+id/btn_dial_number"
4. android:layout_width="match_parent"
5. android:layout_height="wrap_content"
6. android:text="Dial a Number"

android:layout_marginBottom="@dimen/activity_vertical_margin"/>

Sehingga file activity_main.xml kita sekarang menjadi:

<?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:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:orientation="vertical"
tools:context="com.dicoding.associate.myintentapp.MainActivity">
<Button
android:id="@+id/btn_move_activity"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Pindah Activity"
android:layout_marginBottom="@dimen/activity_vertical_margin"/>
<Button
android:id="@+id/btn_move_activity_data"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Pindah Activity dengan Data"
android:layout_marginBottom="@dimen/activity_vertical_margin"/>
<Button
android:id="@+id/btn_dial_number"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Dial a Number"
android:layout_marginBottom="@dimen/activity_vertical_margin"/>
</LinearLayout>

7. Sekarang, buka kembali MainActivity.java dan lanjutkan dengan melakukan


casting tombol Dial Number, set listener dan menambahkan action ketika
tombol diklik.

8. public class MainActivity extends AppCompatActivity implements View.OnClick


Listener{
9. private Button btnMoveActivity;
10. private Button btnMoveWithDataActivity;
11. private Button btnDialPhone;
12. @Override
13. protected void onCreate(Bundle savedInstanceState) {
14. super.onCreate(savedInstanceState);
15. setContentView(R.layout.activity_main);
16. btnMoveActivity = (Button)findViewById(R.id.btn_move_activity);
17. btnMoveActivity.setOnClickListener(this);
18. btnMoveWithDataActivity = (Button)findViewById(R.id.btn_move_activit
y_data);
19. btnMoveWithDataActivity.setOnClickListener(this);
20. btnDialPhone = (Button)findViewById(R.id.btn_dial_number);
21. btnDialPhone.setOnClickListener(this);
22. }
23. @Override
24. public void onClick(View v) {
25. switch (v.getId()){
26. case R.id.btn_move_activity:
27. Intent moveIntent = new Intent(MainActivity.this, MoveActivi
ty.class);
28. startActivity(moveIntent);
29. break;
30. case R.id.btn_move_activity_data:
31. Intent moveWithDataIntent = new Intent(MainActivity.this, Mo
veWithDataActivity.class);
32. moveWithDataIntent.putExtra(MoveWithDataActivity.EXTRA_NAME,
"DicodingAcademy Boy");
33. moveWithDataIntent.putExtra(MoveWithDataActivity.EXTRA_AGE, 5
);
34. startActivity(moveWithDataIntent);
35. break;
36. case R.id.btn_dial_number:
37. String phoneNumber = "081210841382";
38. Intent dialPhoneIntent = new Intent(Intent.ACTION_DIAL, Uri.
parse("tel:"+phoneNumber));
39. startActivity(dialPhoneIntent);
40. break;
41. }
42. }

Setelah selesai, silakan jalankan lagi aplikasi anda dan yeay, anda sudah bisa
men-dial sebuah nomor telepon melalui aplikasi telepon bawaan dari
Android/Device anda. Selamat!
Bedah Kode

String phoneNumber = "081210841382";


Intent dialPhoneIntent = new Intent(Intent.ACTION_DIAL, Uri.parse("
tel:"+phoneNumber));
startActivity(dialPhoneIntent);

Baru saja kita mengimplementasikan penggunaan Intent secara implicit untuk


melakukan proses dial sebuah no telepon. new Intent(Intent.ACTION_DIAL,
Uri.parse("tel:"+phoneNumber)); kita menggunakan inputan new Intent(ACTION,
Uri); pada konstruktor sewaktu menciptakan obyek Intent dimana :
Action : Intent.ACTION_DIAL
Uri : Uri.parse("tel:"+phoneNumber)
Variabel ACTION_DIAL menentukan intent filter dari aplikasi-aplikasi yang bisa
menghandle Action tersebut. Disini aplikasi yang memiliki kemampuan untuk
komunikasi akan tampil pada opsi pilihan yang tampil ke pengguna.
Selain ACTION_DIAL, di Android sudah tersedia berbagai Action yang tinggal
didefinisikan sewaktu menciptakan obyek Intent untuk mengakomodir berbagai
tujuan.
Silakan cek link berikut untuk detailnya :

 Intent

Buat yang belum tau apa itu Uri, berikut penjelasan singkatnya :
Uri adalah sebuah untaian karakter yang digunakan untuk mengidentifikasi nama,
sumber, atau layanan di Internet sesuai dengan RFC 2396.
Pada Uri.parse("tel:"+phoneNumber) kita melakukan parsing Uri dari bentuk teks
String menjadi sebuah obyek Uri dengan menggunakan method
static parse(String). Secara struktur dibagi menjadi :

Dimana “tel” adalah sebuah skema yang disepakati untuk sumber daya telepon dan
phoneNumber adalah variabel String yang bernilai “081210841382”. Skema lain dari
Uri seperti “geo” untuk peta, “http” untuk browser sisanya bisa dilihat di halaman ini :
 Common Intents

Pada prosesnya, pemanggilan Intent secara implicit akan berjalan sesuai dengan
diagram dibawah ini.

1. Aplikasi kita menjalankan Intent untuk ACTION_DIAL melalui startActivity().


2. Sistem Android akan melakukan seleksi terhadap semua aplikasi yang memiliki
kemampuan untuk handle Action tersebut, Sistem Android akan menentukan
aplikasi mana saja yang bisa memproses action berdasarkan
pada IntentFilter pada AndroidManifest.xml masing-masing aplikasi.
Sistem Android akan menampilkan opsi-opsi aplikasi-aplikasi mana saja yang
bisa menghandle action tersebut ke pengguna.
Pengguna memilih salah satu opsi aplikasi dan kemudian sistem Android akan
me-routing ke Activity pada aplikasi yang dipilih yang memiliki Intent-Filter
untuk aksi ACTION_DIAL
3. Aplikasi yang dipilih pun muncul di layar dengan no telepon yang sudah diset.

Masih ada satu lagi yang belum dibahas yaitu Intent ResultActivity, akan tetapi
materi tersebut tidak akan di bahas di dalam kelas ini. Untuk materi yang lebih
lengkap dan komprehensif mengenai Intent ResultActivity bisa langsung daftar
kelas Menjadi Android Developer Expert.
Pada modul sebelumnya anda telah belajar bagaimana mengenal dan memahami
komponen fundamental aplikasi di Android berikut dengan penggunaan beberapa
komponen pembentuk tampilan aplikasi seperti Button dan TextViewagar pengguna
dapat memberikan input dan berinteraksi dengan aplikasi.
Pada bagian ini anda akan mempelajari lebih dalam tentang konsep dasar
pembentukan tampilan antar muka pengguna seperti pemanfaatan komponen-
komponen berbasis View dan ViewGroup yang berkolaborasi sehingga membentuk
sebuah tampilan antar muka pengguna. Contohnya seperti ini,

Keren bukan? Baik, kita mulai saja pembahasannya.


Pada dasarnya semua elemen antar pengguna di aplikasi android dibangun
menggunakan dua buah komponen inti yaitu : View dan ViewGroup.
Sebuah View adalah obyek yang menggambar komponen tampilan ke layar yang
mana pengguna dapat melihat dan berinteraksi langsung.
Contoh komponen turunan dari View seperti :
 TextView, komponen yang berguna untuk menampilkan teks ke layar.
 Button, komponen yang membuat pengguna dapat berinteraksi dengan cara
ditekan untuk melakukan sesuatu.
 ImageView, Komponen untuk menampilkan gambar.
 ListView, komponen untuk menampilkan informasi dalam bentuk list.
 GridView, komponen untuk menampilkan informasi dalam bentuk grid.
 RadioButton, komponen yang memungkinkan pengguna dapat memilih satu
pilihan dari berbagai pilihan yang disediakan.
 Checkbox, komponen yang memungkinkan pengguna dapat memilih lebih dari
satu dari pilihan yang ada.
Sedangkan ViewGroup adalah sebuah obyek yang mewadahi obyek-
obyek View dan ViewGroup itu sendiri sehingga membentuk satu kesatuan tampilan
aplikasi yang utuh. ViewGroup lebih seperti :
 LinearLayout
 FrameLayout
 RelativeLayout
 TableLayout

Secara hierarki dalam pembentukan tampilan pengguna, kolaborasi


penggunaan antara komponen Viewdan
komponen ViewGroup memungkinkan seperti ini :

Jika diterjemahkan di dalam sebuah ViewGroup akan ditampung dua buah


komponen View dan satu komponen ViewGroup yang terdiri dari 3 buah
komponen View.
Ya, ini sudah bersifat bertingkat atau nested.
Untuk membuat anda lebih jago lagi, kami merekomendasikan anda untuk membaca
lebih detail tentang materi di atas pada link berikut ini :

 User Interface Overview

Salah satu contoh dari tampilan dalam file layout xml untuk merepresentasikan
kolaborasi View dan ViewGroupseperti ini :

1. <?xml version="1.0" encoding="utf-8"?>


2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
3. android:layout_width="match_parent"
4. android:layout_height="match_parent"
5. android:orientation="vertical" >
6. <TextView android:id="@+id/text"
7. android:layout_width="wrap_content"
8. android:layout_height="wrap_content"
9. android:text="I am a TextView" />
10. <Button android:id="@+id/button"
11. android:layout_width="wrap_content"
12. android:layout_height="wrap_content"
13. android:text="I am a Button" />
14. </LinearLayout>

Obyek turunan ViewGroup LinearLayout menjadi kontainer untuk obyek


turunan View, Button, dan TextView guna membentuk sebuah tampilan melalui file
layout xml. Beberapa
komponen ViewGroup seperti LinearLayout, RelativeLayout, FrameLayout, dan
TableLayout merupakan komponen yang paling banyak digunakan untuk menjadi
parent / root dari komponen-komponen View di dalam sebuah tampilan aplikasi
android. Berikut adalah definisi singkat dan inti dari komponen-komponen tersebut
terhadap penempatan komponen View (child) di dalamnya.

LinearLayout
Akan menempatkan komponen-komponen di dalamnya secara horizontal atau
vertikal. LinearLayout memilikiatribut weight untuk masing-masing child view yang
berguna untuk mengontrol porsi ukuran view secara Relatif dalam sebuah ruang
(space) yangtersedia.
android:orientation=”vertical” android:orientation=”horizontal”
Cek link ini tentang linearlayout :

 Linear Layout

RelativeLayout
Layout yang paling fleksible dikarenakan posisi dari masing-masing komponen di
dalamnya dapat mengacu secara relatif pada komponen yang lainnya dan juga dapat
mengacu secara relatif ke batas layar.
Cek link ini tentang relativelayout

 Relative Layout

FrameLayout
Layout ini adalah layout yang paling sederhana. Layout ini akan membuat komponen
yang ada di dalamnya menjadi menumpuk atau saling menutupi satu dengan yang
lainnya. Komponen yang paling pertama pada layout ini akan menjadi bagian bawah
dari komponen-komponen di atasnya. Pada materi penggunaan fragment di materi
sebelumnya, FrameLayout memiliki kemampuan untuk menjadi kontainer
buat fragment-fragment di dalam sebuah Activity. Berikut ilustrasi dari
penggunaan FrameLayout terhadap child view yang dimiliki di dalamnya.

Cek link ini tentang framelayout


 Frame Layout

TableLayout

Susunan komponen di dalam TableLayout akan berada dalam baris dan kolom.
Namun jangan berharap layout jenis ini akan menampilkan garis pembatas untuk
baris, kolom atau cell-nya menggunakan konsep yang sama pada pengembangan
aplikasi berbasis web.
Cek link ini tentang TableLayout :

 Grid Layout

Jika anda sadari sebetulnya perbedaan dari masing-masing layout yang dijelaskan di
atas terletak pada susunan komponen view di dalamnya. Itu saja.
Lalu pertanyaannya kapan kita
menggunakan LinearLayout, RelativeLayout, FrameLayout dan TableLayout ?
Jawabannya adalah relatif tergantung pada kebutuhan dan performa.
Salah satu tips performa dari aplikasi android adalah dengan membuat susunan
hierarki layout dalam sebuah file layout xml secara sederhana dan flat dalam artian
kedalaman penggunaan nested layout atau layout bersarang tidak terlalu dalam.
Selain itu, pemahaman yang baik terhadap dasar-dasar pembangunan UI di android,
pengalaman, feeling, dan selalu mencari tahu best-practice seperti apa.
Semua tergantung latihan dan seberapa sering kita berhadapan dengan kasus-kasus
melakukan transformasi UI dari bentuk mockup ke dalam bentuk kode xml di Android.
Dengan membiasakan melakukan penulisan kode sisi UI di xml tanpa penggunaan
drag and drop akan membentuk pola pikir dan feeling kita dalam membangun dan
mentransformasi UI ke dalam bentuk yang dibutuhkan. Ini bersifat Relatif, mungkin
cara membentuk UI dari satu developer android dengan developer android lainnya
akan berbeda.
Untuk lebih detail pemahaman tentang layout dapat dicek pada halaman ini :

 Declaring Layout
Kelemahan dari layout-layout tersebut adalah ketidakmampuan untuk melakukan
scroll konten secara vertikal atau horizontal. Jelas, adakalanya tampilan aplikasi anda
memuat informasi yang panjangnya melebihi layar yang ada, jika hanya bergantung
pada layout-layout yang dijelaskan sebelumnya maka tampilan aplikasi anda akan
terpotong. Di situlah peran ScrollView membantu untuk memberikan solusi.

ScrollView
Adalah layout yang akan membuat komponen di dalamnya dapat digeser (scroll)
secara vertical dan horizontal. Komponen di dalam Scrollview hanya diperbolehkan
memiliki 1 parent utama dari LayoutLinear, RelativeLayout, FrameLayout,
atau TableLayout.

 ScrollView

Satuan Dimensi di Android


Platform Android dikenal karena keberagamannya, dari mulai ukuran device, layar,
spesifikasi, hingga level operating system-nya. Karena keberagaman tersebut tak
heran jika dibutuhkan tampilan yang konsisten agar aplikasi kita bisa berjalan dan
tampil maksimal khususnya di beragam jenis layar device android yang beredar di
pasaran.
Android sendiri memiliki satuan unit dimensi untuk ukuran tinggi dan lebar sebuah
komponen View atauViewGroup. Berikut adalah esensi dari satuan dimensi unit di
android.
1. Ekosistem android dikenal dengan fragmentasi spesifikasi device yang sangat
bervariasi termasuk perbedaan dimensi layar dan kerapatan pixel (density)
dari layar di masing-masing jenis layar device
2. Untuk tampilan yang konsisten di handset Android terdapat satuan untuk
dimensi dan ukuran dari teks yaitu : dip/dp (density-independent pixel)
dan sp (scale-independent pixels).
3. Satuan dp/dip digunakan untuk satuan dari nilai dimensi misal width (attribut
: layout_width) dan height (attribut : layout_height) dari sebuah
komponen View atau ViewGroup.
4. Satuan sp digunakan untuk ukuran teks. Perbedaannya
dengan dp / dip adalah satuan sp android akan men-scale ukuran teks sesuai
dengan setting ukuran teks di device (yang biasa dapat di akses melalui menu
settings)

Contoh 1 :

Misalkan ada dua tablet 7-inch (ukuran diagonal layar), tablet pertama (A) memiliki
resolusi layar 1200x1920px 320dpi dan yang lainnya (B) beresolusi 2048x1536px
326dpi. Membuat button dengan ukuran 300x300px mungkin akan tampak normal
pada tablet A tapi akan tampak kecil di tablet B.

Tapi akan berbeda jika kita spesifikasikan ukuran button-nya dengan ukuran yang
bergantung pada density layar alias menggunakan dip misal 300x300dp. Secara fisik
ukuran button tersebut akan selalu sama pada ukuran layar yang berbeda.

Contoh 2 :

Pada gambar di atas ukuran 200dp akan dikonversi pada device mdpi (device dengan
density 160dpi/dots per inch) menjadi 200px dan menjadi 400px pada device xhdpi
(density 420dpi) misal pada nexus 4. Sehingga ukuran tersebut tampak sama dan
konsisten secara fisik untuk beragam device dengan ukuran layar yang berbeda.
Link-link berikut akan membantu anda untuk jauh lebih memahami bagaimana aplikasi
anda bisa mendukung banyak layar device.

 Multiple Screen Support


 Screen Density
 DPI Screen
 DP / PX Converter
 Video Density-independent Pixels
 Density Pixal dan Scale Pixel

Terasa kurang jika pemahaman esensi materi di atas tidak dilengkapi dengan praktik
langsung. Jadi, siap untuk ngoding lagi ?


Tujuan

Pada latihan kali ini anda akan mengembangkan sebuah halaman detail yang di
dalamnya terdiri beberapa implementasi View dan ViewGroup Layout. Tampilan
akhir aplikasi kita akan seperti ini :
Codelab Views and ViewGroup

1. Buat project baru di android studio dengan nama MyViewAndViews untuk API
level 15 dan emptyactivity.
2. Lalu buka file build.gradle (Module: app) dan tambahkan satu baris ini di
bagian dependecies :

1. compile 'de.hdodenhof:circleimageview:2.1.0'

Sehingga file build.gradle(Module: app) kita sekarang seperti ini :

2. apply plugin: 'com.android.application'


3.
4. android {
5. compileSdkVersion 24
6. buildToolsVersion "24.0.2"
7. defaultConfig {
8. applicationId "com.dicoding.myviewandviews"
9. minSdkVersion 15
10. targetSdkVersion 24
11. versionCode 1
12. versionName "1.0"
13. testInstrumentationRunner "android.support.test.runner.Androi
dJUnitRunner"
14. }
15. buildTypes {
16. release {
17. minifyEnabled false
18. proguardFiles getDefaultProguardFile('proguard-android.tx
t'), 'proguard-rules.pro'
19. }
20. }
21. }
22.
23. dependencies {
24. compile fileTree(dir: 'libs', include: ['*.jar'])
25. androidTestCompile('com.android.support.test.espresso:espresso-co
re:2.2.2', {
26. exclude group: 'com.android.support', module: 'support-annota
tions'
27. })
28. compile 'com.android.support:appcompat-v7:24.2.1'
29. testCompile 'junit:junit:4.12'
30. compile 'de.hdodenhof:circleimageview:2.1.0'
31. }
3. Lalu buka file strings.xml di res → values dan sesuaikan isinya dengan seperti
ini (Anda boleh copy paste ini),
1. <resources>
2. <string name="app_name">MyViewAndViews</string>
3. <string name="content_text">Google officially announced its much-
anticipated Pixel phones; the Pixel and Pixel XL, on October 4. We at
tended Google’s London UK event, mirroring the main one taking place
in San Francisco, US, where the firm unwrapped the new Android 7.1 No
ugat devices which will apparently usurp Google’s long-standing Nexus
series.</string>
4. <string name="content_specs_display">5.0 inches\n
5. FHD AMOLED at 441ppi\n
6. 2.5D Corning® Gorilla® Glass 4</string>
7. <string name="content_specs_size">5.6 x 2.7 x 0.2 ~ 0.3 inches 14
3.8 x 69.5 x 7.3 ~ 8.5 mm</string>
8. <string name="content_specs_battery">2,770 mAh battery\n
9. Standby time (LTE): up to 19 days\n
10. Talk time (3g/WCDMA): up to 26 hours\n
11. Internet use time (Wi-Fi): up to 13 hours\n
12. Internet use time (LTE): up to 13 hours\n
13. Video playback: up to 13 hours\n
14. Audio playback (via headset): up to 110 hours\n
15. Fast charging: up to 7 hours of use from only 15 minutes of charg
ing</string>
16. </resources>
4. Selanjutnya, anda download aset yang dibutuhkan di sini atau anda bisa
menggunakan aset yang anda inginkan sebagai pengganti. Jika telah selesai,
anda copy semua aset yang dibutuhkan ke dalam direktori res → drawable.
5. Buka file activity_main.xml dan lengkapi kodenya seperti berikut :
1. <?xml version="1.0" encoding="utf-8"?>
2. <ScrollView xmlns:android="http://schemas.android.com/apk/res/android
"
3. xmlns:tools="http://schemas.android.com/tools"
4. android:id="@+id/activity_main"
5. android:layout_width="match_parent"
6. android:layout_height="match_parent"
7. android:background="@android:color/white"
8. tools:context="com.dicoding.myviewandviews.MainActivity">
9. <LinearLayout
10. android:layout_width="match_parent"
11. android:layout_height="wrap_content"
12. android:orientation="vertical">
13. <FrameLayout
14. android:layout_width="match_parent"
15. android:layout_height="wrap_content">
16. <ImageView
17. android:layout_width="match_parent"
18. android:layout_height="wrap_content"
19. android:adjustViewBounds="true"
20. android:src="@drawable/pixel_google"
21. android:scaleType="fitXY"/>
22. <TextView
23. android:layout_width="wrap_content"
24. android:layout_height="wrap_content"
25. android:padding="8dp"
26. android:text="6 Photos"
27. android:gravity="center_vertical"
28. android:drawableLeft="@drawable/ic_collections_white_
18dp"
29. android:drawablePadding="4dp"
30. android:textAppearance="@style/TextAppearance.AppComp
at.Small"
31. android:background="#4D000000"
32. android:textColor="@android:color/white"
33. android:layout_marginLeft="@dimen/activity_horizontal
_margin"
34. android:layout_marginBottom="@dimen/activity_vertical
_margin"
35. android:layout_gravity="bottom" />
36. </FrameLayout>
37. <TextView
38. android:layout_width="match_parent"
39. android:layout_height="wrap_content"
40. android:textSize="32sp"
41. android:text="$735"
42. android:layout_marginLeft="@dimen/activity_horizontal_mar
gin"
43. android:layout_marginRight="@dimen/activity_horizontal_ma
rgin"
44. android:layout_marginTop="@dimen/activity_vertical_margin
"
45. android:layout_marginBottom="8dp"
46. android:textColor="@android:color/black"/>
47. <TextView
48. android:layout_width="match_parent"
49. android:layout_height="wrap_content"
50. android:text="Stock hanya 5 buah"
51. android:textSize="12sp"
52. android:layout_marginLeft="@dimen/activity_horizontal_mar
gin"
53. android:layout_marginRight="@dimen/activity_horizontal_ma
rgin"
54. android:layout_marginBottom="@dimen/activity_vertical_mar
gin"/>
55. <TextView
56. android:layout_width="match_parent"
57. android:layout_height="wrap_content"
58. android:text="@string/content_text"
59. android:layout_marginLeft="@dimen/activity_horizontal_mar
gin"
60. android:layout_marginRight="@dimen/activity_horizontal_ma
rgin"
61. android:layout_marginBottom="@dimen/activity_vertical_mar
gin"
62. android:lineSpacingMultiplier="1"
63. android:textColor="@android:color/black"/>
64. <TextView
65. android:layout_width="match_parent"
66. android:layout_height="wrap_content"
67. android:text="Spesifikasi"
68. android:textSize="12sp"
69. android:layout_marginLeft="@dimen/activity_horizontal_mar
gin"
70. android:layout_marginRight="@dimen/activity_horizontal_ma
rgin"
71. android:layout_marginBottom="8dp"/>
72. <TableLayout
73. android:layout_width="match_parent"
74. android:layout_height="wrap_content"
75. android:layout_marginLeft="@dimen/activity_horizontal_mar
gin"
76. android:layout_marginRight="@dimen/activity_horizontal_ma
rgin"
77. android:layout_marginBottom="@dimen/activity_vertical_mar
gin">
78. <TableRow
79. android:layout_width="match_parent"
80. android:layout_height="wrap_content"
81. android:layout_marginBottom="8dp">
82. <TextView
83. android:layout_width="wrap_content"
84. android:layout_height="wrap_content"
85. android:textSize="14sp"
86. android:layout_marginRight="@dimen/activity_verti
cal_margin"
87. android:text="Display"/>
88. <TextView
89. android:layout_width="match_parent"
90. android:layout_height="wrap_content"
91. android:textSize="14sp"
92. android:layout_weight="1"
93. android:text="@string/content_specs_display"
94. android:textColor="@android:color/black"/>
95. </TableRow>
96. <TableRow
97. android:layout_width="match_parent"
98. android:layout_height="wrap_content"
99. android:layout_marginBottom="8dp">
100. <TextView
101. android:layout_width="wrap_content"
102. android:layout_height="wrap_content"
103. android:textSize="14sp"
104. android:layout_marginRight="@dimen/activity_v
ertical_margin"
105. android:text="Size"/>
106. <TextView
107. android:layout_width="match_parent"
108. android:layout_height="wrap_content"
109. android:textSize="14sp"
110. android:layout_weight="1"
111. android:text="@string/content_specs_size"
112. android:textColor="@android:color/black"/>
113. </TableRow>
114. <TableRow
115. android:layout_width="match_parent"
116. android:layout_height="wrap_content"
117. android:layout_marginBottom="8dp">
118. <TextView
119. android:layout_width="wrap_content"
120. android:layout_height="wrap_content"
121. android:textSize="14sp"
122. android:layout_marginRight="@dimen/activity_v
ertical_margin"
123. android:text="Battery"/>
124. <TextView
125. android:layout_width="match_parent"
126. android:layout_height="wrap_content"
127. android:textSize="14sp"
128. android:layout_weight="1"
129. android:text="@string/content_specs_battery"
130. android:textColor="@android:color/black"/>
131. </TableRow>
132. </TableLayout>
133. <TextView
134. android:layout_width="match_parent"
135. android:layout_height="wrap_content"
136. android:text="Dijual oleh"
137. android:textSize="12sp"
138. android:layout_marginLeft="@dimen/activity_horizontal
_margin"
139. android:layout_marginRight="@dimen/activity_horizonta
l_margin"
140. android:layout_marginBottom="8dp"/>
141. <RelativeLayout
142. android:layout_width="match_parent"
143. android:layout_height="wrap_content"
144. android:layout_marginLeft="@dimen/activity_horizontal
_margin"
145. android:layout_marginRight="@dimen/activity_horizonta
l_margin"
146. android:layout_marginBottom="@dimen/activity_vertical
_margin">
147. <de.hdodenhof.circleimageview.CircleImageView
148. android:layout_width="56dp"
149. android:layout_height="56dp"
150. android:src="@drawable/photo_2"
151. android:layout_centerVertical="true"
152. android:id="@+id/profile_image"
153. android:layout_marginRight="@dimen/activity_horiz
ontal_margin"/>
154. <TextView
155. android:layout_width="match_parent"
156. android:layout_height="wrap_content"
157. android:layout_toRightOf="@id/profile_image"
158. android:text="Narenda Wicaksono"
159. android:textColor="@android:color/black"
160. android:layout_centerVertical="true"/>
161. </RelativeLayout>
162. <Button
163. android:layout_width="match_parent"
164. android:layout_height="wrap_content"
165. android:text="Beli"
166. android:layout_marginLeft="@dimen/activity_horizontal
_margin"
167. android:layout_marginRight="@dimen/activity_horizonta
l_margin"
168. android:layout_marginBottom="@dimen/activity_vertical
_margin"/>
169. </LinearLayout>
170. </ScrollView>
6. Pada properties android:text pasti akan ada warning yang tulisannya seperti
dibawah ini.
Ini terjadi ketika kita hardcode(menuliskan text string langsung pada view) pada
android:text. Solusinya adalah tekan alt+enter dengan arahkan cursor pada isi
dari android:text, maka akan muncul dialog seperti ini.
Dan kemudian pilihlah Extract string resource, nanti akan muncul dialog baru
lagi yang tampilannya seperti ini
Kemudian tekan OK.
Dialog tersebut akan otomatis menambahkan text yang kita hardcode ke dalam
res → strings.xml secara otomatis.

7. Lakukan juga untuk warning dari android:text lainnya dari semua view yang ada
pada activity_main.xml. Kemudian buka res → strings.xml, maka isi dari xmlnya
akan menjadi seperti berikut.

1. <resources>
2. <string name="app_name">MyViewAndViews</string>
3. <string name="content_text">Google officially announced its much-
anticipated Pixel phones; the Pixel and Pixel XL, on October 4. We at
tended Google’s London UK event, mirroring the main one taking place
in San Francisco, US, where the firm unwrapped the new Android 7.1 No
ugat devices which will apparently usurp Google’s long-standing Nexus
series.</string>
4. <string name="content_specs_display">5.0 inches\n
5. FHD AMOLED at 441ppi\n
6. 2.5D Corning® Gorilla® Glass 4</string>
7. <string name="content_specs_size">5.6 x 2.7 x 0.2 ~ 0.3 inches 14
3.8 x 69.5 x 7.3 ~ 8.5 mm</string>
8. <string name="content_specs_battery">2,770 mAh battery\n
9. Standby time (LTE): up to 19 days\n
10. Talk time (3g/WCDMA): up to 26 hours\n
11. Internet use time (Wi-Fi): up to 13 hours\n
12. Internet use time (LTE): up to 13 hours\n
13. Video playback: up to 13 hours\n
14. Audio playback (via headset): up to 110 hours\n
15. Fast charging: up to 7 hours of use from only 15 minutes of c
harging</string>
16. <string name="stock_hanya_5_buah">Stock hanya 5 buah</string>
17. <string name="spesifikasi">Spesifikasi</string>
18. <string name="display">Display</string>
19. <string name="size">Size</string>
20. <string name="battery">Battery</string>
21. <string name="dijual_oleh">Dijual oleh</string>
22. <string name="narenda_wicaksono">Narenda Wicaksono</string>
23. <string name="beli">Beli</string>
24. <string name="_735">$735</string>
25. <string name="_6_photos">6 photos</string>
26. </resources>
8. Diketik ya, lumayan panjang bukan?. Oke terakhir
pada MainActivity tambahkan satu baris berikut :
1. getSupportActionBar().setTitle("Google Pixel");

Sehingga kode yang ada di MainActivity menjadi seperti berikut :

2. public class MainActivity extends AppCompatActivity {


3.
4. @Override
5. protected void onCreate(Bundle savedInstanceState) {
6. super.onCreate(savedInstanceState);
7. setContentView(R.layout.activity_main);
8.
9. getSupportActionBar().setTitle("Google Pixel");
10. }
11. }
9. Dan sekarang silakan jalankan aplikasinya dan lihat hasilnya seharusnya
sudah mirip dengan yang ada di atas bukan? Selamat!

Bedah Kode

Tidak ada yang rumit dibagian ini karena anda hanya berhadapan dengan bagaimana
membentuk sebuah tampilan aplikasi android yang bagus di file layout xml.
Di awal kita melakukan penambahan dependency untuk menampilkan sebuah custom
ImageView dalam bentuk lingkaran dengan menggunakan
library CircleImageView yang dibuat oleh Henning Dodenhoff. Library ini cukup
populer dan selalu di-maintain dengan baik.

1. compile 'de.hdodenhof:circleimageview:2.1.0'

Selanjutnya, kita akan menambahkan variabel-variabel konstan yang ditulis di dalam


file strings.xml sehingga nantinya teks yang sama tidak akan ditulis dua kali, baik itu
di file Activity maupun file xml.
1. <resources>
2. <string name="app_name">MyViewAndViews</string>
3. <string name="content_text">Google officially announced its much-antici
pated Pixel phones; the Pixel and Pixel XL, on October 4. We attended Googl
e’s London UK event, mirroring the main one taking place in San Francisco,
US, where the firm unwrapped the new Android 7.1 Nougat devices which will
apparently usurp Google’s long-standing Nexus series.</string>
4. <string name="content_specs_display">5.0 inches\n
5. FHD AMOLED at 441ppi\n
6. 2.5D Corning® Gorilla® Glass 4</string>
7. <string name="content_specs_size">5.6 x 2.7 x 0.2 ~ 0.3 inches 143.8 x
69.5 x 7.3 ~ 8.5 mm</string>
8. <string name="content_specs_battery">2,770 mAh battery\n
9. Standby time (LTE): up to 19 days\n
10. Talk time (3g/WCDMA): up to 26 hours\n
11. Internet use time (Wi-Fi): up to 13 hours\n
12. Internet use time (LTE): up to 13 hours\n
13. Video playback: up to 13 hours\n
14. Audio playback (via headset): up to 110 hours\n
15. Fast charging: up to 7 hours of use from only 15 minutes of chargin
g</string>
16. <string name="stock_hanya_5_buah">Stock hanya 5 buah</string>
17. <string name="spesifikasi">Spesifikasi</string>
18. <string name="display">Display</string>
19. <string name="size">Size</string>
20. <string name="battery">Battery</string>
21. <string name="dijual_oleh">Dijual oleh</string>
22. <string name="narenda_wicaksono">Narenda Wicaksono</string>
23. <string name="beli">Beli</string>
24. <string name="_735">$735</string>
25. <string name="_6_photos">6 photos</string>
26. </resources>

Dan jika anda perhatikan, jika kita ingin menampilkan teks‘content_specs_size’ hanya
perlu menuliskan sebagai nilai atribut di dalam obyekTextView yang diinginkan.

1. <TextView
2. android:layout_width="match_parent"
3. android:layout_height="wrap_content"
4. android:textSize="14sp"
5. android:layout_weight="1"
6. android:text="@string/content_specs_size"
7. android:textColor="@android:color/black"/>

Dan ya, dengan memanfaatkan strings.xml akan membuat anda lebih mudah
nantinya dalam membuat aplikasi ke dalam banyak bahasa.
Jika anda telah membaca dan memahami materi tentang Activity sebelumnya maka
seharusnya anda tidak akan bingung dengan atribut dan namespace yang digunakan
ketika kita membuat sebuah tampilan aplikasi pada file layout xml. Jadi silakan dibaca
kembali jika anda merasa lupa atau kurang paham.

1. <ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
2. xmlns:tools="http://schemas.android.com/tools"
3. android:id="@+id/activity_main"
4. android:layout_width="match_parent"
5. android:layout_height="match_parent"
6. android:background="@android:color/white"
7. tools:context="com.dicoding.myviewandviews.MainActivity">
8.
9. ...
10.
11. </ScrollView>

Ingat, semua komponen View dan ViewGroup memiliki dua buah atribut terpenting
yang harus selalu diberikan nilai untuk mengatur posisi dirinya di dalam sebuat layout,
yaitu :

 layout_width
 layout_height

Kita akan menggunakan sebuah obyek ScrollView yang akan menjadi Root untuk
tampilan halaman aplikasi. Kenapa menggunakan ScrollView sebagai root / parent
karena kita ingin tampilan halaman dari aplikasi kita bisa di scroll ke bawah dan ke
atas sehingga pengguna dapat melihat tampilan secara menyeluruh.

1. <ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
2. xmlns:tools="http://schemas.android.com/tools"
3. android:id="@+id/activity_main"
4. android:layout_width="match_parent"
5. android:layout_height="match_parent"
6. android:background="@android:color/white"
7. tools:context="com.dicoding.myviewandviews.MainActivity">
8. <LinearLayout
9. android:layout_width="match_parent"
10. android:layout_height="wrap_content"
11. android:orientation="vertical">
12. ...
13. </LinearLayout>
14. </ScrollView>

Seperti yang dijelaskan sebelumnya, bahwa ScrollView hanya diperbolehkan


memiliki satu layout ViewGroup sebagai parent / root untuk obyek view di dalamnya.
Di sini susunan komponen view akan berada dalam orientasi vertikal.

1. <FrameLayout
2. android:layout_width="match_parent"
3. android:layout_height="wrap_content">
4. <ImageView
5. android:layout_width="match_parent"
6. android:layout_height="wrap_content"
7. android:adjustViewBounds="true"
8. android:src="@drawable/pixel_google"
9. android:scaleType="fitXY"/>
10. <TextView
11. android:layout_width="wrap_content"
12. android:layout_height="wrap_content"
13. android:padding="8dp"
14. android:text="6 Photos"
15. android:gravity="center_vertical"
16. android:drawableLeft="@drawable/ic_collections_white_18dp"
17. android:drawablePadding="4dp"
18. android:textAppearance="@style/TextAppearance.AppCompat.Small"
19. android:background="#4D000000"
20. android:textColor="@android:color/white"
21. android:layout_marginLeft="@dimen/activity_horizontal_margin"
22. android:layout_marginBottom="@dimen/activity_vertical_margin"
23. android:layout_gravity="bottom" />
24. </FrameLayout>

Gambar pixel_google yang tampil akan menjadi alas bagi obyek TextView yang
berada di atasnya. Ini seperti sifat dari komponen FrameLayout itu sendiri terhadap
urutan posisi atau struktur di dalamnya.

1. <TableLayout
2. android:layout_width="match_parent"
3. android:layout_height="wrap_content"
4. android:layout_marginLeft="@dimen/activity_horizontal_margin"
5. android:layout_marginRight="@dimen/activity_horizontal_margin"
6. android:layout_marginBottom="@dimen/activity_vertical_margin">
7. <TableRow
8. android:layout_width="match_parent"
9. android:layout_height="wrap_content"
10. android:layout_marginBottom="8dp">
11. <TextView
12. android:layout_width="wrap_content"
13. android:layout_height="wrap_content"
14. android:textSize="14sp"
15. android:layout_marginRight="@dimen/activity_vertical_margin"
16. android:text="Display"/>
17. <TextView
18. android:layout_width="match_parent"
19. android:layout_height="wrap_content"
20. android:textSize="14sp"
21. android:layout_weight="1"
22. android:text="@string/content_specs_display"
23. android:textColor="@android:color/black"/>
24. </TableRow>
25. <TableRow
26. android:layout_width="match_parent"
27. android:layout_height="wrap_content"
28. android:layout_marginBottom="8dp">
29. <TextView
30. android:layout_width="wrap_content"
31. android:layout_height="wrap_content"
32. android:textSize="14sp"
33. android:layout_marginRight="@dimen/activity_vertical_margin"
34. android:text="Size"/>
35. <TextView
36. android:layout_width="match_parent"
37. android:layout_height="wrap_content"
38. android:textSize="14sp"
39. android:layout_weight="1"
40. android:text="@string/content_specs_size"
41. android:textColor="@android:color/black"/>
42. </TableRow>
43. <TableRow
44. android:layout_width="match_parent"
45. android:layout_height="wrap_content"
46. android:layout_marginBottom="8dp">
47. <TextView
48. android:layout_width="wrap_content"
49. android:layout_height="wrap_content"
50. android:textSize="14sp"
51. android:layout_marginRight="@dimen/activity_vertical_margin"
52. android:text="Battery"/>
53. <TextView
54. android:layout_width="match_parent"
55. android:layout_height="wrap_content"
56. android:textSize="14sp"
57. android:layout_weight="1"
58. android:text="@string/content_specs_battery"
59. android:textColor="@android:color/black"/>
60. </TableRow>
61. </TableLayout>

Kita menggunakan TableLayout untuk menampilkan informasi spesifikasi dari


perangkat Google Pixel. Tidak seperti pada umumnya TableLayout disini sangat
sederhana dan tidak akan ada garis pembatas untuk kolom dan baris bahkan cell-nya.
Hanya dengan menggunakan TableRow kita bisa menambahkan sebuah baris baru
di dalam sebuah TableLayout.

1. <RelativeLayout
2. android:layout_width="match_parent"
3. android:layout_height="wrap_content"
4. android:layout_marginLeft="@dimen/activity_horizontal_margin"
5. android:layout_marginRight="@dimen/activity_horizontal_margin"
6. android:layout_marginBottom="@dimen/activity_vertical_margin">
7. <de.hdodenhof.circleimageview.CircleImageView
8. android:layout_width="56dp"
9. android:layout_height="56dp"
10. android:src="@drawable/photo_2"
11. android:layout_centerVertical="true"
12. android:id="@+id/profile_image"
13. android:layout_marginRight="@dimen/activity_horizontal_margin"/>
14. <TextView
15. android:layout_width="match_parent"
16. android:layout_height="wrap_content"
17. android:layout_toRightOf="@id/profile_image"
18. android:text="Narenda Wicaksono"
19. android:textColor="@android:color/black"
20. android:layout_centerVertical="true"/>
21. </RelativeLayout>

Selanjutnya, kita menggunakan sebuah RelativeLayout untuk menampilkan sebuah


image dan teks, di mana posisi dari teks mengacu ke sebelah kanan dari image dan
posisi keduanya disesuaikan untuk berada di tengah secara vertikal.

1. getSupportActionBar().setTitle("Google Pixel");

Baris di atas akan mengganti nilai dari judul halaman pada ActionBar di
dalam MainActivity. Kenapa menggunakan getSupportActionBar() ? Karena
kelas MainActivity inherit kepada AppCompatActivity yang merupakan kelas
turunan Activity. Kelas tersebut sudah menyediakan fasilitas
komponen ActionBar dan mampu mendukung untuk kompabilitas ke semua versi OS
android.
Selamat ! Anda sudah belajar tentang layout, view, dan ViewGroup sejauh ini dan
semakin sering anda berlatih untuk mentransformasikan sebuah desain menjadi
sebuah file layout xml tampilan aplikasi android maka akan semakin mahir anda.
Setelah ini silakan anda main-main lebih dalam lagi dan mencari tahu tentang
implementasi material design di aplikasi android.
Anda bisa mengunjungi tiga website ini untuk mencari inspirasi ketika membangun
sebuah User Interface untuk aplikasi anda.
Pada bagian ini anda akan belajar dengan prinsip desain yang ada di android dan
bagaimana mengimplementasikan sebuah struktur yang mendefinisikan tampilan
sebuah view dan tampilan komponen aplikasi secara menyeluruh dalam sebuah file
style. Prinsip dasar dalam merancang antarmuka aplikasi android harus mematuhi
kaidah yang ditetapkan oleh Design Guideline yang dibuat oleh tim Android di
Google. Diantaranya adalah sebagai berikut :

1. Desain diperuntukkan untuk interaksi sentuh.


2. Menampilkan informasi yang hanya dibutuhkan.
3. Jika aplikasi meminta izin pengguna untuk melakukan sebuah aksi maka harus
disiapkan pula mekanisme agar pengguna dapat membatalkan aksi yang telah
dilakukan.
4. Lakukan interupsi jika diperlukan.
5. Menampilkan dan mempertahankan teks secara singkat dan prioritaskan
penggunaan gambar jika diperlukan untuk lebih deskriptif.
6. Jaga data pengguna.
7. Permudah pengguna untuk melakukan sesuatu yang penting secara cepat.
8. Jika terlihat sama maka harus berperilaku sama.
9. Bantu pengguna untuk membuat keputusan tapi tetap biarkan pengguna yang
menentukan.

Best Practice
Terdapat beberapa langkah-langkah terbaik (best practice) yang harus diperhatikan
ketika mengembangkan sebuah aplikasi android, ini korelasi antara User Interface dan
menuliskan kode dari sisi logika aplikasi.
1. Desain yang baik untuk performa aplikasi
Aplikasi yang dirancang dengan baik harus dapat dijalankan dengan cepat dan
jika terdapat proses yang memakan waktu, maka lakukan secara background
dan asynchronous
2. Desain yang baik agar aplikasi dapat bersifat responsif
Berikan feedback ke pengguna terhadap sebuah aksi yang dilakukan
contohnya jika pengguna menekan sebuah tombol di aplikasi maka harus
menampilkan efek tekan.
3. Desain yang mengakomodasi kebutuhan informasi yang dibutuhkan
pengguna
Aplikasi anda harus menampilkan informasi yang dibutuhkan oleh pengguna
dan jika diperlukan aplikasi bisa menampilkan informasi terakhir yang diperoleh
atau dijalankan sebelumnya sehingga pengguna tidak perlu lagi menunggu
aplikasi melakukan load data dari server.
4. Desain untuk optimasi menggunakan baterai
Usahakan aplikasi anda menggunakan daya baterai yang kecil. Minimalisir
penggunaan dari background service yang tidak perlu dan stop semua listener
jika aplikasi tidak sedang dijalankan.
Manfaatkan GcmNetworkManager dan JobScheduler jika memang terdapat
task yang harus dilakukan secara periodik.
5. Desain untuk menggunakan koneksi jaringan yang efisien.
Aplikasi yang baik adalah salah satunya pintar dalam melakukan efisiensi
koneksi ke jaringan internet dan memilah-milah mana task yang harus
dijalankan pada saat posisi device pengguna terhubung ke wifi (unmetered
network) atau pun network lain. Penggunaan koneksi jaringan yang baik akan
menjadi hal wajib jika aplikasi andaingin tetap digunakan oleh pengguna.

Ternyata tidak sedikit bukan aturan dalam mengembangkan aplikasi android yang
baik. Nilai yang bagus pada poin tampilan akan menopang kualitas fungsi di aplikasi
yang anda buat. Jangan sampai fungsi dari aplikasi anda bagus namun secara
tampilan jelek dan begitu pula sebaliknya. Pengguna akan mempertahankan aplikasi
andadan tetap menggunakannya selama aplikasi anda memang dibutuhkan dan
memenuhi poin-poin di atas.
Kembali lagi pada topik style dan theme. Jika anda pernah mengembangkan sebuah
aplikasi berbasis web seharusnya anda sudah tidak asing lagi dengan
file CSS (Cascading Style Sheet) yang merupakan sebuah file yang mendefinisikan
bagaimana komponen dan tampilan sebuah halaman website. Pendekatan yang
serupa juga berlaku di android, ini yang dinamakan style.
Style merupakan sebuah kumpulan property yang dibutuhkan untuk mendefinisikan
bagaimana sebuah komponen View dan layar jendela
(bisa Activity maupun fragment) ditampilkan seperti
property height, width, background_color dan lain sebagainya. Style terdefinisi
dalam file xml sendiri, anda bisa menemukannya di res → values → styles.xml.
Contoh umumnya anda memiliki sebuah TextView yang berisi berbagai attribute
seperti ini. Let’s say ini adalah obyek TextView untuk menampilkan konten dari detail
informasi yang terdapat di keseluruhan aplikasi dan diimplementasikan di banyak file
layout xml.

1. <TextView
2. android:layout_width="match_parent"
3. android:layout_height="wrap_content"
4. android:textColor="#00FF00"
5. android:typeface="monospace"
6. android:text="@string/hello" />

Akan sangat tidak efektif jika kita hanya melakukan copy paste dari satu layout xml ke
layout xml lainnya yang sebetulnya bisa kita sederhanakan seperti ini :

1. <TextView
2. style="@style/CodeFont"
3. android:text="@string/hello" />

Attribute layout_width, layout_height, textColor, dan typeface bisa kita pindahkan


menjadi sebuah style sendiri untuk TextView tersebut dan dapat digunakan kembali
untuk semua obyek TextView sejenis.

1. <?xml version="1.0" encoding="utf-8"?>


2. <resources>
3. <style name="CodeFont" parent="@android:style/TextAppearance.Medium">
4. <item name="android:layout_width">match_parent</item>
5. <item name="android:layout_height">wrap_content</item>
6. <item name="android:textColor">#00FF00</item>
7. <item name="android:typeface">monospace</item>
8. </style>
9. </resources>

Beberapa aturan yang harus diperhatikan ketika kita menggunakan styles yaitu:

1. Semua style yang dibuat harus berada dalam tag <resources></resources>


2. Semua style yang ingin didefinisikan harus berada dalam tag <style></style>

1. <style name="CodeFont" parent="@android:style/TextAppearance.Medium">

Name : Nama dari style yang anda buat.

Parent : Nilai style yang akan mewarisi dari style (berikut dengan attribute
di dalamnya) yang telah ada, umumnya bawaan dari sdk ataupun platform.
Style yang akan kita warisi akan dapat anda ubah dan tambahkan nilai attribute
dalam style baru yang anda buat. Di android sendiri sudah menyediakan
beragam style yang bisa anda gunakan untuk beragam tampilan.

3. Semua attribut yang akan didefinisikan dalam sebuah style harus berada
dalam tag <item></item

1. <item name="android:layout_width">match_parent</item>

Name : Nama atribut yang ingin didefinisikan.

Match_parent : Nilai dari atribut tersebut.

Andaikan dalam satu kasus anda ingin membuat varian dari style yang telah anda
buat. Misal untuk style CodeFrontanda ingin ada yang berwarna merah anda bisa
menambahkan style baru dengan hanya menambahkan prefix dari style sebelumnya
dan nama dari style yang baru dipisahkan oleh titik seperti ini :

1. <style name="CodeFont.Red">
2. <item name="android:textColor">#FF0000</item>
3. </style>

atau berwarna merah dan juga dengan ukuran yang besar menjadi seperti ini :

1. <style name="CodeFont.Red">
2. <item name="android:textColor">#FF0000</item>
3. <item name="android:textSize">30sp</item>
4. </style>

Mudah bukan? Anda baru saja belajar tentang bagaimana sebuah style dibuat dan
diimplementasikan, selanjutnya bagaimana dengan theme?
Theme atau tema itu sendiri merupakan sebuah style yang diimplementasikan
khusus untuk Activity dan Applicationpada file AndroidManifest.xml. Pada project
sebelumnya kita mendefinisikannya seperti ini :

1. android:theme="@style/AppTheme"

Dimana AppTheme pada styles.xml berisi :

1. <resources>
2. <!-- Base application theme. -->
3. <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
4. <!-- Customize your theme here. -->
5. <item name="colorPrimary">@color/colorPrimary</item>
6. <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
7. <item name="colorAccent">@color/colorAccent</item>
8. </style>
9. </resources>

Sebuah styles yang inherit ke tema AppCompat untuk varian light dan
memiliki DarkActionBar. Semua nilai pada atribut terdapat pada file colors.xml yang
berisi

1. <resources>
2. <color name="colorPrimary">#3F51B5</color>
3. <color name="colorPrimaryDark">#303F9F</color>
4. <color name="colorAccent">#FF4081</color>
5. </resources>

Saat ini pengembangan aplikasi Android mengacu pada implementasi guideline


material design sebagai konsep utama dalam
mengembangkan user interface dan user experience. Anda bisa mempelajari lebih
lanjut tentang material design di android pada link ini :

 Material Design
Semenjak konsep material design ditetapkan sebagai acuan utama untuk
pengembangan user interface dan userexperience terdapat penyederhanaan
dalam pendefinisian komponen inti dari atribut yang digunakan. Pada gambar di atas
bisa dilihat titik-titik mana saja yang hanya kita gunakan untuk menjadi fondasi dasar
tampilan style aplikasi yang kita buat.
Kalau anda penasaran dengan versi sebelum material design maka anda harus
melihat video ini :

 Video From Holo to Material

Ok, saya tahu anda sudah tidak sabar ingin ngoding dan tenang tidak akan banyak
kode yang anda tulis kali ini.
Kita akan memodifikasi dari project sebelumnya dan mengimplementasikan teori di
atas.
Tujuan

Pada Codelab kali kita akan menerapkan Style dan Theme pada sample aplikasi
yang telah kita buat sebelumnya pada modul Views dan ViewsGroup. Beberapa poin
yang didapatkan pada materi ini adalah :

1. Bagaimana memanfaatkan Style pada aplikasi?


2. Bagaimana memanfaatkan Theme pada aplikasi?

Codelab Style dan Theme

1. Buka kembali project sebelumnya (MyViewAndViews) dan buka


file colors.xml di res → values → colors.xml dan ubah setiap nilai yang ada
saat ini dengan nilai-nilai berikut
1. <?xml version="1.0" encoding="utf-8"?>
2. <resources>
3. <color name="colorPrimary">#607D8B</color>
4. <color name="colorPrimaryDark">#455A64</color>
5. <color name="colorAccent">#FF5722</color>
6. <color name="colorSubTitle">#757575</color>
7. </resources>

2. Selanjutnya, buka file styles.xml di res → values → styles.xml dan


tambahkan beberapa style tambahan menjadi seperti ini :
1. <resources>
2.
3. <!-- Base application theme. -->
4. <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
5. <!-- Customize your theme here. -->
6. <item name="colorPrimary">@color/colorPrimary</item>
7. <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
8. <item name="colorAccent">@color/colorAccent</item>
9. </style>
10.
11. <style name="TextContent" parent="@style/TextAppearance.AppCompat">
12. <item name="android:layout_width">wrap_content</item>
13. <item name="android:layout_height">wrap_content</item>
14. <item name="android:layout_marginLeft">@dimen/activity_horizonta
l_margin</item>
15. <item name="android:layout_marginRight">@dimen/activity_horizont
al_margin</item>
16. </style>
17.
18. <style name="TextContent.Small">
19. <item name="android:textAppearance">@style/TextAppearance.AppCom
pat.Small</item>
20. </style>
21.
22. <style name="TextContent.Small.White">
23. <item name="android:textColor">@android:color/white</item>
24. </style>
25.
26. <style name="TextContent.Subtitle">
27. <item name="android:textColor">@color/colorSubTitle</item>
28. <item name="android:textSize">12sp</item>
29. </style>
30.
31. <style name="TextContent.Black">
32. <item name="android:textColor">@android:color/black</item>
33. </style>
34.
35. <style name="TextSpec">
36. <item name="android:textSize">14sp</item>
37. </style>
38.
39. <style name="TextSpec.Field">
40. <item name="android:layout_width">wrap_content</item>
41. <item name="android:layout_height">wrap_content</item>
42. <item name="android:layout_marginRight">16dp</item>
43. <item name="android:textColor">@color/colorSubTitle</item>
44.
45. </style>
46. <style name="TextSpec.Value">
47. <item name="android:layout_width">match_parent</item>
48. <item name="android:layout_height">wrap_content</item>
49. <item name="android:layout_weight">1</item>
50. <item name="android:textColor">@android:color/black</item>
51. </style>
52. </resources>

3. Jika selesai, kita akan implementasikan style-style yang barusan dibuat ke


dalam file activity_main.xml dan kondisikan seperti ini :
1. <?xml version="1.0" encoding="utf-8"?>
2. <ScrollView xmlns:android="http://schemas.android.com/apk/res/androi
d"
3. xmlns:tools="http://schemas.android.com/tools"
4. android:id="@+id/activity_main"
5. android:layout_width="match_parent"
6. android:layout_height="match_parent"
7. android:background="@android:color/white"
8. tools:context="com.dicoding.myviewandviews.MainActivity">
9. <LinearLayout
10. android:layout_width="match_parent"
11. android:layout_height="wrap_content"
12. android:orientation="vertical">
13. <FrameLayout
14. android:layout_width="match_parent"
15. android:layout_height="wrap_content">
16. <ImageView
17. android:layout_width="match_parent"
18. android:layout_height="wrap_content"
19. android:adjustViewBounds="true"
20. android:src="@drawable/pixel_google"
21. android:scaleType="fitXY"/>
22. <TextView
23. style="@style/TextContent.Small.White"
24. android:padding="8dp"
25. android:text="@string/_6_photos"
26. android:gravity="center_vertical"
27. android:drawableLeft="@drawable/ic_collections_white
_18dp"
28. android:drawablePadding="4dp"
29. android:textAppearance="@style/TextAppearance.AppCom
pat.Small"
30. android:background="#4D000000"
31. android:layout_marginLeft="@dimen/activity_horizonta
l_margin"
32. android:layout_marginBottom="@dimen/activity_vertica
l_margin"
33. android:layout_gravity="bottom" />
34. </FrameLayout>
35. <TextView
36. style="@style/TextContent.Black"
37. android:textSize="32sp"
38. android:text="@string/_735"
39. android:layout_marginTop="@dimen/activity_vertical_margi
n"
40. android:layout_marginBottom="8dp"/>
41. <TextView
42. style="@style/TextContent.Subtitle"
43. android:text="@string/stock_hanya_5_buah"
44. android:layout_marginBottom="@dimen/activity_vertical_ma
rgin"/>
45. <TextView
46. style="@style/TextContent"
47. android:text="@string/content_text"
48. android:layout_marginBottom="@dimen/activity_vertical_ma
rgin"
49. android:lineSpacingMultiplier="1"
50. android:textColor="@android:color/black"/>
51. <TextView
52. style="@style/TextContent.Subtitle"
53. android:text="@string/spesifikasi"
54. android:layout_marginBottom="8dp"/>
55. <TableLayout
56. android:layout_width="match_parent"
57. android:layout_height="wrap_content"
58. android:layout_marginLeft="@dimen/activity_horizontal_ma
rgin"
59. android:layout_marginRight="@dimen/activity_horizontal_m
argin"
60. android:layout_marginBottom="@dimen/activity_vertical_ma
rgin">
61. <TableRow
62. android:layout_width="match_parent"
63. android:layout_height="wrap_content"
64. android:layout_marginBottom="8dp">
65. <TextView
66. style="@style/TextSpec.Field"
67. android:text="@string/display"/>
68. <TextView
69. style="@style/TextSpec.Value"
70. android:text="@string/content_specs_display"/>
71. </TableRow>
72. <TableRow
73. android:layout_width="match_parent"
74. android:layout_height="wrap_content"
75. android:layout_marginBottom="8dp">
76. <TextView
77. style="@style/TextSpec.Field"
78. android:text="@string/size"/>
79. <TextView
80. style="@style/TextSpec.Value"
81. android:text="@string/content_specs_size"/>
82. </TableRow>
83. <TableRow
84. android:layout_width="match_parent"
85. android:layout_height="wrap_content"
86. android:layout_marginBottom="8dp">
87. <TextView
88. style="@style/TextSpec.Field"
89. android:text="@string/battery"/>
90. <TextView
91. style="@style/TextSpec.Value"
92. android:text="@string/content_specs_battery"/>
93. </TableRow>
94. </TableLayout>
95. <TextView
96. style="@style/TextContent.Subtitle"
97. android:text="@string/dijual_oleh"
98. android:layout_marginBottom="8dp"/>
99. <RelativeLayout
100. android:layout_width="match_parent"
101. android:layout_height="wrap_content"
102. android:layout_marginLeft="@dimen/activity_horizontal
_margin"
103. android:layout_marginRight="@dimen/activity_horizonta
l_margin"
104. android:layout_marginBottom="@dimen/activity_vertical
_margin">
105. <de.hdodenhof.circleimageview.CircleImageView
106. android:layout_width="56dp"
107. android:layout_height="56dp"
108. android:src="@drawable/photo_2"
109. android:layout_centerVertical="true"
110. android:id="@+id/profile_image"
111. android:layout_marginRight="@dimen/activity_horiz
ontal_margin"/>
112. <TextView
113. style="@style/TextContent"
114. android:layout_toRightOf="@id/profile_image"
115. android:text="@string/narenda_wicaksono"
116. android:layout_centerVertical="true"/>
117. </RelativeLayout>
118. <Button
119. android:layout_width="match_parent"
120. android:layout_height="wrap_content"
121. android:text="@string/beli"
122. android:layout_marginLeft="@dimen/activity_horizontal
_margin"
123. android:layout_marginRight="@dimen/activity_horizonta
l_margin"
124. android:layout_marginBottom="@dimen/activity_vertical
_margin"/>
125. </LinearLayout>
126. </ScrollView>

4. Jika selesai coba jalankan aplikasi anda dan seharusnya hasilnya menjadi
seperti ini.
Terlihat lebih bagus bukan ?
Dan perhatikan penulisan di setiap obyek TextView akan menjadi lebih
sederhana contohnya sebagai berikut :

1. <TextView
2. style="@style/TextContent.Subtitle"
3. android:text="@string/dijual_oleh"
4. android:layout_marginBottom="8dp"/>
5. Hmm ada yang kurang lengkap rasanya, tombol kita masih dalam posisi
default. Sekarang, kita coba ubah agar lebih menyatu dengan tema aplikasi
kita saat ini. Buka kembali styles.xml dan tambahkan baris-baris ini di atas
tag </resources>
1. <style name="ButtonGeneral" parent="@style/Widget.AppCompat.Button.C
olored">
2. <item name="android:layout_width">match_parent</item>
3. <item name="android:layout_height">wrap_content</item>
4. <item name="android:layout_marginRight">@dimen/activity_horizont
al_margin</item>
5. <item name="android:layout_marginLeft">@dimen/activity_horizonta
l_margin</item>
6. <item name="android:layout_marginBottom">@dimen/activity_vertica
l_margin</item>
7. </style>

6. Kemudian pada activity_main.xml kondisikan bagian obyek Button menjadi


seperti ini :
1. <Button
2. style="@style/ButtonGeneral"
3. android:text="Beli"/>
7. Jalankan kembali aplikasi anda dan seharusnya tampilannya akan menjadi
seperti ini.
Sekarang coba anda klik dan tahan, jika device android anda berada di bawah
lollipop (API level 21) seharusnya otomatis akan menampilkan warna lebih
gelap sedangkan jika di atas lollipop akan ada efek air (ripple) ketika
obyek Button anda klik.
Akan secara otomatis mengambil nilai accentColor sebagai nilai warna
indikator aktif untuk obyek Button dan nilai pada
attribute colorButtonNormal sebagai nilai gelap ketika obyek Button ditekan.

Selesai! Saat ini anda sudah memahami bagaimana theme dan style diterapkan
dalam membangun sebuah aplikasi di Android. Pengelompokan attribute
untuk View yang sama akan lebih memudahkan anda dalam menentukan dan
penyeragaman format View yang akan ditampilkan ke dalam layar.
Seperti biasa, untuk lebih membuat anda paham tentang materi ini kami
rekomendasikan anda untuk membaca lebih lanjut di :

 Ui Theme
 Material Design

Selamat ! Satu langkah besar sudah anda lalui, sekarang ayo kita lanjut ke materi
yang lebih seru!
Pada materi tentang loader sebelumnya kita telah belajar bagaimana menampilkan
kumpulan data dalam bentuk sebuah list. Kita menggunakan obyek ListView untuk
menampilkan data-data yang berasal dari kontak di device pengguna ke layar. Sangat
sederhana tapi sangat berarti. Kenapa? Pada dasarnya interaksi umum antara
pengguna dengan aplikasi dalam menampilkan data dalam jumlah yang banyak
adalah dengan menggunakan list yang bisa di-scroll ke atas dan ke bawah hanya
dengan menggunakan jempol tangan kanan.
ListView menjadi komponen pertama yang mengakomodasi hal tersebut, namun
semenjak Google merilis pendekatan desain
bernama material design, RecyclerView menjadi pilihan pertama yang harus
developer gunakan. Anda masih bisa menggunakan kedua komponen tersebut secara
berdampingan dalam satu aplikasi.
Secara definisi RecyclerView adalah sebuah komponen tampilan (widget) yang
lebih canggih ketimbang pendahulunya ListView dan bersifat lebih fleksibel. Dan
yang paling penting adalah RecyclerView memiliki kemampuan untuk menampilkan
data secara efisien dalam jumlah yang besar. Terlebih jika anda memiliki koleksi data
yang tiap elemennya mampu berubah-ubah sewaktu dijalankan (runtime) karena
interaksi pengguna atau karena adanya pengaruh dari jaringan internet.

Gambar di atas akan menjelaskan beberapa komponen yang harus anda tahu
sebelum menggunakan RecyclerView.

1. RecyclerView dan LayoutManager: Komponen user interface yang


bertugas untuk menampilkan data set yang dimiliki di dalamnya
terdapat LayoutManager yang mana akan mengatur posisi tampilan data baik
itu secara List (Vertikal), Grid (Baris dan Kolom) atau StaggeredGrid (Grid
yang memiliki susunan tak seragam / tak beraturan)
2. Adapter : Komponen yang akan mengatur bagaimana tampilan data set ke
dalam RecyclerView. Di sinilah terjadi proses pengisian tampilan
(ViewInflate) dari file layout xml untuk tiap elemen dari set data yang dimiliki
sebelum dipasang (bind) ke dalam RecyclerView.
3. Dataset : Kumpulan data yang dimiliki dan ingin ditampilkan bisa
berupa Array, List maupun obyek map.
4. Item Animator : Ini yang spesial, kita bisa set animasi untuk tiap item di
dalamnya bahkan bisa membuat kustomisasi animasi. Contoh animasi yang
umum seperti penambahan (add) dan penghapusan (removal) item. Kita akan
mempelajari hal ini pada materi terpisah.

Langkah-langkah mengimplementasikan RecyclerView sebagai berikut :


1. Tambahkan dependencies komponen RecyclerView pada
file build.gradle (module: app) level modul.
2. Tambahkan obyek RecyclerView di file layout xml dari Activity / Fragment.
3. Definisikan model kelas (POJO) yang akan digunakan sebagai data source.
4. Buat file layout xml untuk baris item di RecyclerView.
5. Buat sebuah kelas adapter yang inherit
ke RecyclerView.Adapter dan ViewHolder untuk menampilkan tiap elemen
data.
6. Definisikan obyek RecyclerView berikut dengan bentuk yang diinginkan (bisa
dalam bentuk list, grid, atau staggered) dan selanjutnya pasang
obyek adapter (binding) agar bisa menampilkan koleksi data ke
dalam RecyclerView.

Untuk membuat anda makin paham tentang RecyclerView kami sarankan anda
untuk lanjut membaca materi pada link berikut

 List Cards
 Recycler View


Tujuan

Baik, pada Codelab kali ini kalian akan belajar menampilkan data Presiden Republik
Indonesia ke dalam sebuah RecyclerView. Beberapa poin yang akan dikover dalam
materi ini adalah :

1. Bagaimana menggunakan RecyclerView ke dalam aplikasi ?


2. Berbagai macam RecyclerView seperti List, Grid, dan CardView.
3. Membuat CustomItemOnClickListener pada RecyclerView.
4. Menambahkan menu pada ActionBar

Contoh dari RecyclerView yang akan kita buat dalam tiga bentuk :
1. Dalam bentuk List
2. Dalam bentuk Grid
3. Dan menampilkan list dengan bentuk kartu menggunakan CardView
Semuanya berada dalam satu halaman saja dengan cukup menambahkan
menuseperti berikut:
Keren bukan? Baik, agar anda tidak penasaran lagi ayo kita langsung mulai koding.

Codelab List View

1. Buat project baru dengan nama MyRecyclerView dengan minimal level SDK
di 15 dan dengan template MainActivity di pilihan EmptyActivity.

2. Setelah terbentuk, tambahkan beberapa dependencies yang akan kita


gunakan pada file build.gradle (module: app) di bagian dependencies seperti
berikut :
1. compile 'com.android.support:recyclerview-v7:25.0.0'
2. compile 'de.hdodenhof:circleimageview:2.1.0'
3. compile 'com.github.bumptech.glide:glide:3.7.0'
4. compile 'com.android.support:cardview-v7:25.0.0'

Sehingga secara keseluruhan file build.gradle(module: app) anda akan


seperti ini :

5. apply plugin: 'com.android.application'


6. android {
7. compileSdkVersion 25
8. buildToolsVersion "24.0.2"
9. defaultConfig {
10. applicationId "com.dicoding.myapplication"
11. minSdkVersion 15
12. targetSdkVersion 25
13. versionCode 1
14. versionName "1.0"
15. testInstrumentationRunner "android.support.test.runner.Androi
dJUnitRunner"
16. }
17. buildTypes {
18. release {
19. minifyEnabled false
20. proguardFiles getDefaultProguardFile('proguard-android.tx
t'), 'proguard-rules.pro'
21. }
22. }
23. }
24.
25. dependencies {
26. compile fileTree(include: ['*.jar'], dir: 'libs')
27. androidTestCompile('com.android.support.test.espresso:espresso-co
re:2.2.2', {
28. exclude group: 'com.android.support', module: 'support-annota
tions'
29. })
30. compile 'com.android.support:appcompat-v7:25.0.0'
31. testCompile 'junit:junit:4.12'
32. compile 'com.android.support:recyclerview-v7:25.0.0'
33. compile 'de.hdodenhof:circleimageview:2.1.0'
34. compile 'com.github.bumptech.glide:glide:3.7.0'
35. compile 'com.android.support:cardview-v7:25.0.0'
36. }

Yang anda harus perhatikan adalah Android Studio anda harus tetap up-to-
date, baik itu dari sisi editor maupun Android SDK tools, platform tools, build
tools, dan android support repository. Anda bisa mengeceknya di menu bar
tools → Android → SDK Manager → Launch stand alone SDK Manager seperti
berikut :

3. Selanjutnya pada activity_main.xml lengkapi kodenya menjadi seperti berikut


:
1. <?xml version="1.0" encoding="utf-8"?>
2. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/and
roid"
3. xmlns:tools="http://schemas.android.com/tools"
4. android:id="@+id/activity_main"
5. android:layout_width="match_parent"
6. android:layout_height="match_parent"
7. tools:context="com.dicoding.myapplication.MainActivity">
8. <android.support.v7.widget.RecyclerView
9. android:id="@+id/rv_category"
10. android:layout_width="match_parent"
11. android:layout_height="match_parent"/>
12. </RelativeLayout>
4. Setelah selesai kita akan membuat beberapa kelas terkait koleksi data yang
ingin ditampilkan, buat kelas baru dengan nama PresidentData dan lengkapi
kodenya menjadi seperti berikut :
1. public class PresidentData {
2. public static String[][] data = new String[][]{
3. {"Soekarno", "Presiden Pertama RI", "https://upload.wikim
edia.org/wikipedia/commons/thumb/0/01/Presiden_Sukarno.jpg/418px-Pre
siden_Sukarno.jpg"},
4. {"Soeharto", "Presiden Kedua RI", "https://upload.wikimed
ia.org/wikipedia/commons/thumb/5/59/President_Suharto%2C_1993.jpg/46
8px-President_Suharto%2C_1993.jpg"},
5. {"Bacharuddin Jusuf Habibie", "Presiden Ketiga RI", "http
s://upload.wikimedia.org/wikipedia/commons/thumb/f/f1/Bacharuddin_Ju
suf_Habibie_official_portrait.jpg/520px-Bacharuddin_Jusuf_Habibie_of
ficial_portrait.jpg"},
6. {"Abdurrahman Wahid", "Presiden Keempat RI", "https://upl
oad.wikimedia.org/wikipedia/commons/thumb/3/35/President_Abdurrahman
_Wahid_-_Indonesia.jpg/486px-President_Abdurrahman_Wahid_-_Indonesia
.jpg"},
7. {"Megawati Soekarnoputri", "Presiden Kelima RI", "https:/
/upload.wikimedia.org/wikipedia/commons/thumb/8/88/President_Megawat
i_Sukarnoputri_-_Indonesia.jpg/540px-President_Megawati_Sukarnoputri
_-_Indonesia.jpg"},
8. {"Susilo Bambang Yudhoyono", "Presiden Keenam RI", "https
://upload.wikimedia.org/wikipedia/commons/5/58/Presiden_Susilo_Bamba
ng_Yudhoyono.png"},
9. {"Joko Widodo", "Presiden Ketujuh RI", "https://upload.wi
kimedia.org/wikipedia/commons/1/1c/Joko_Widodo_2014_official_portrai
t.jpg"}
10. };
11.
12. public static ArrayList<President> getListData(){
13. President president = null;
14. ArrayList<President> list = new ArrayList<>();
15. for (int i = 0; i <data.length; i++) {
16. president = new President();
17. president.setName(data[i][0]);
18. president.setRemarks(data[i][1]);
19. president.setPhoto(data[i][2]);
20.
21. list.add(president);
22. }
23.
24. return list;
25. }
26. }
5. Kemudian buat lagi satu kelas model data bernama President dan lengkapi
kodenya menjadi seperti berikut :
1. public class President {
2. private String name, remarks, photo;
3.
4. public String getName() {
5. return name;
6. }
7.
8. public void setName(String name) {
9. this.name = name;
10. }
11.
12. public String getRemarks() {
13. return remarks;
14. }
15.
16. public void setRemarks(String remarks) {
17. this.remarks = remarks;
18. }
19.
20. public String getPhoto() {
21. return photo;
22. }
23.
24. public void setPhoto(String photo) {
25. this.photo = photo;
26. }
27. }

6. Setelah selesai dengan model data, saatnya kita membuat sebuah item
tampilan dalam bentuk file layout xml yang akan ditampilkan di RecyclerView.
Karena pertama kali akan ditampilkan dalam bentuk list maka kita buat dengan
nama item_row_president dengan cara klik kanan pada direktori layout →
new → layout resource file dan lengkapi kodenya menjadi seperti berikut :
1. <?xml version="1.0" encoding="utf-8"?>
2. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/and
roid"
3. android:orientation="horizontal" android:layout_width="match_parent"
4. android:layout_height="wrap_content"
5. android:padding="@dimen/activity_vertical_margin">
6. <de.hdodenhof.circleimageview.CircleImageView
7. android:id="@+id/img_item_photo"
8. android:layout_width="55dp"
9. android:layout_height="55dp"
10. android:layout_marginRight="@dimen/activity_horizontal_margin"/>
11. <LinearLayout
12. android:layout_width="match_parent"
13. android:layout_height="wrap_content"
14. android:layout_toRightOf="@id/img_item_photo"
15. android:layout_centerVertical="true"
16. android:orientation="vertical">
17. <TextView
18. android:id="@+id/tv_item_name"
19. android:layout_width="match_parent"
20. android:layout_height="wrap_content"
21. android:text="Name"
22. android:textStyle="bold"
23. android:textSize="16sp"
24. android:layout_marginBottom="8dp"/>
25. <TextView
26. android:id="@+id/tv_item_remarks"
27. android:layout_width="match_parent"
28. android:layout_height="wrap_content"
29. android:text="Remarks"/>
30. </LinearLayout>
31. </RelativeLayout>

7. Setelah selesai dengan model data dan file layout xml sekarang saatnya kita
membuat sebuah kelas adapter yang akan memformat bagaimana tiap elemen
dari koleksi data yang kita punya ditampilkan. Buat kelas adapter secara
manual dengan klik kanan pada package utama → new → Java Class dan beri
nama ListPresidentAdapter. Setelah tercipta lengkapi kodenya menjadi
seperti berikut :
1. public class ListPresidentAdapter extends RecyclerView.Adapter<ListPr
esidentAdapter.CategoryViewHolder>{
2. private Context context;
3.
4. public ArrayList<President> getListPresident() {
5. return listPresident;
6. }
7. public void setListPresident(ArrayList<President> listPresident)
{
8. this.listPresident = listPresident;
9. }
10.
11. private ArrayList<President>listPresident;
12.
13. public ListPresidentAdapter(Context context) {
14. this.context = context;
15. }
16.
17. @Override
18. public CategoryViewHolder onCreateViewHolder(ViewGroup parent, in
t viewType) {
19. View itemRow = LayoutInflater.from(parent.getContext()).infla
te(R.layout.item_row_president, parent, false);
20. return new CategoryViewHolder(itemRow);
21. }
22.
23. @Override
24. public void onBindViewHolder(CategoryViewHolder holder, int posit
ion) {
25.
26. holder.tvName.setText(getListPresident().get(position).getNam
e());
27. holder.tvRemarks.setText(getListPresident().get(position).get
Remarks());
28.
29. Glide.with(context)
30. .load(getListPresident().get(position).getPhoto())
31. .override(55, 55)
32. .crossFade()
33. .into(holder.imgPhoto);
34. }
35.
36. @Override
37. public int getItemCount() {
38. return getListPresident().size();
39. }
40.
41. class CategoryViewHolder extends RecyclerView.ViewHolder{
42. TextView tvName;
43. TextView tvRemarks;
44. ImageView imgPhoto;
45.
46. public CategoryViewHolder(View itemView) {
47. super(itemView);
48. tvName = (TextView)itemView.findViewById(R.id.tv_item_nam
e);
49. tvRemarks = (TextView)itemView.findViewById(R.id.tv_item_
remarks);
50. imgPhoto = (ImageView)itemView.findViewById(R.id.img_item
_photo);
51. }
52. }
53. }

8. Seperti yang tertulis pada langkah-langkah di atas, sekarang setelah semua


komponennya terbuat, kita modifikasi file kelas MainActivity sehingga menjadi
:
1. public class MainActivity extends AppCompatActivity {
2. private RecyclerView rvCategory;
3. private ArrayList<President>list;
4.
5. @Override
6. protected void onCreate(Bundle savedInstanceState) {
7. super.onCreate(savedInstanceState);
8. setContentView(R.layout.activity_main);
9. rvCategory = (RecyclerView)findViewById(R.id.rv_category);
10. rvCategory.setHasFixedSize(true);
11.
12. list = new ArrayList<>();
13. list.addAll(PresidentData.getListData());
14.
15. showRecyclerList();
16. }
17.
18. private void showRecyclerList(){
19. rvCategory.setLayoutManager(new LinearLayoutManager(this));
20. ListPresidentAdapter listPresidentAdapter = new ListPresident
Adapter(this);
21. listPresidentAdapter.setListPresident(list);
22. rvCategory.setAdapter(listPresidentAdapter);
23. }
24. }

9. Karena data gambar yang kita miliki berasal dari internet maka kita harus
menambahkan sebuah permission ke dalam file AndroidManifest.xml yang
kita miliki. Tambahkan satu baru berikut di atas tag <application>
1. <uses-permission android:name="android.permission.INTERNET" />

Sehingga secara keseluruhan file AndroidManifest.xml yang kita miliki saat


ini menjadi seperti berikut :

2. <?xml version="1.0" encoding="utf-8"?>


3. <manifest xmlns:android="http://schemas.android.com/apk/res/android"
4. package="com.dicoding.myapplication">
5.
6. <uses-permission android:name="android.permission.INTERNET" />
7.
8. <application
9. android:allowBackup="true"
10. android:icon="@mipmap/ic_launcher"
11. android:label="@string/app_name"
12. android:supportsRtl="true"
13. android:theme="@style/AppTheme">
14. <activity android:name=".MainActivity">
15. <intent-filter>
16. <action android:name="android.intent.action.MAIN" />
17.
18. <category android:name="android.intent.category.LAUNC
HER" />
19. </intent-filter>
20. </activity>
21. </application>
22.
23. </manifest>

10. Sekarang coba jalankan terlebih dahulu aplikasi yang kita buat dan seharusnya
hasilnya akan seperti berikut :
Keren..
Satu bentuk RecyclerView untuk menampilkan data Presiden Republik
Indonesia sudah tercipta.

Selanjutnya ayo kita lengkapi lagi.

11. Ok perhatikan pada hasil yang dijelaskan di awal kita memiliki satu mekanisme
untuk menampilkan bentuk dari RecyclerView yaitu dengan memanfaatkan
fasilitas menu, sekarang mari kita buat.

Langkah pertama adalah dengan membuat resource directory terkait yang


mana resource directory menu tidak secara default disediakan. Ok klik kanan
pada direktori res → new → android resource directory. Setelah muncul dialog
box seperti di bawah ini, isikan menu pada field directory name. Klik OK untuk
menyelesaikannya.

12. Selanjutnya setelah terbuat direktori menu, klik kanan pada direktori tersebut
→ new → menu resource file, beri nama menu_main pada field file name dan
setelah terbentuk lengkapi kodenya menjadi seperti berikut :
1. <?xml version="1.0" encoding="utf-8"?>
2. <menu xmlns:android="http://schemas.android.com/apk/res/android"
3. xmlns:app="http://schemas.android.com/apk/res-auto">
4. <item
5. android:id="@+id/action_list"
6. android:title="List"
7. app:showAsAction="never"/>
8. <item
9. android:id="@+id/action_grid"
10. android:title="Grid"
11. app:showAsAction="never"/>
12. <item
13. android:id="@+id/action_cardview"
14. android:title="with CardView"
15. app:showAsAction="never"/>
16. </menu>

13. Setelah selesai, saatnya kita pasang file menu tersebut


di MainActivity dengan menambahkan dua method berikut :
1. @Override
2. public boolean onCreateOptionsMenu(Menu menu) {
3. getMenuInflater().inflate(R.menu.menu_main, menu);
4. return super.onCreateOptionsMenu(menu);
5. }
6.
7. @Override
8. public boolean onOptionsItemSelected(MenuItem item) {
9.
10. switch (item.getItemId()){
11. case R.id.action_list:
12.
13. break;
14.
15. case R.id.action_grid:
16.
17. break;
18.
19. case R.id.action_cardview:
20.
21. break;
22. }
23. return super.onOptionsItemSelected(item);
24. }

Untuk dua method di atas anda bisa menggunakan ctrl (tahan) + spasi untuk
menampilkan code assistant pada android studio.

Sekarang seharusnya kelas MainActivity kita saat ini berisi seperti berikut :

25. public class MainActivity extends AppCompatActivity {


26. private RecyclerView rvCategory;
27. private ArrayList<President>list;
28.
29. @Override
30. protected void onCreate(Bundle savedInstanceState) {
31. super.onCreate(savedInstanceState);
32. setContentView(R.layout.activity_main);
33.
34. rvCategory = (RecyclerView)findViewById(R.id.rv_category);
35. rvCategory.setHasFixedSize(true);
36.
37. list = new ArrayList<>();
38. list.addAll(PresidentData.getListData());
39.
40. showRecyclerList();
41. }
42. private void showRecyclerList(){
43. rvCategory.setLayoutManager(new LinearLayoutManager(this));
44. ListPresidentAdapter listPresidentAdapter = new ListPresident
Adapter(this);
45. listPresidentAdapter.setListPresident(list);
46. rvCategory.setAdapter(listPresidentAdapter);
47. }
48.
49. @Override
50. public boolean onCreateOptionsMenu(Menu menu) {
51. getMenuInflater().inflate(R.menu.menu_main, menu);
52. return super.onCreateOptionsMenu(menu);
53. }
54.
55. @Override
56. public boolean onOptionsItemSelected(MenuItem item) {
57.
58. switch (item.getItemId()){
59. case R.id.action_list:
60.
61. break;
62.
63. case R.id.action_grid:
64.
65. break;
66.
67. case R.id.action_cardview:
68.
69. break;
70. }
71. return super.onOptionsItemSelected(item);
72. }
73. }
Sekarang coba jalankan kembali aplikasimu dan seharusnya akan seperti ini
tampilannya.

 Setelah menu tercipta, mari kita lanjutkan pembuatan bentuk
dari RecyclerView yang lain. Kita mulai lagi dari bentuk Grid. Buat sebuah file
layout xml baru dengan nama item_grid_president dan lengkapi kodenya
menjadi seperti berikut :

o <?xml version="1.0" encoding="utf-8"?>


o <LinearLayout xmlns:android="http://schemas.android.com/apk/res/andro
id"
o android:orientation="vertical" android:layout_width="match_parent"
o android:layout_height="wrap_content">
o <ImageView
o android:id="@+id/img_item_photo"
o android:layout_width="match_parent"
o android:layout_height="250dp"
o android:scaleType="centerCrop"
o android:layout_margin="1dp"/>
o </LinearLayout>
 Setelah selesai, lanjut ke pembuatan adapter untuk file layout xml tersebut.
Buat sebuah kelas baru dengan nama GridPresidentAdapter dan lengkapi
kodenya menjadi seperti berikut :
o public class GridPresidentAdapter extends RecyclerView.Adapter<GridPr
esidentAdapter.GridViewHolder> {
o private Context context;
o private ArrayList<President>listPresident;
o
o public ArrayList<President> getListPresident() {
o return listPresident;
o }
o
o public void setListPresident(ArrayList<President> listPresident)
{
o this.listPresident = listPresident;
o }
o
o public GridPresidentAdapter(Context context) {
o this.context = context;
o }
o
o @Override
o public GridViewHolder onCreateViewHolder(ViewGroup parent, int vi
ewType) {
o View view = LayoutInflater.from(parent.getContext()).inflate(
R.layout.item_grid_president, parent, false);
o GridViewHolder gridViewHolder = new GridViewHolder(view);
o return gridViewHolder;
o }
o
o @Override
o public void onBindViewHolder(GridViewHolder holder, int position)
{
o Glide.with(context)
o .load(getListPresident().get(position).getPhoto())
o .override(350, 550)
o .into(holder.imgPhoto);
o }
o
o @Override
o public int getItemCount() {
o return getListPresident().size();
o }
o public class GridViewHolder extends RecyclerView.ViewHolder{
o ImageView imgPhoto;
o public GridViewHolder(View itemView) {
o super(itemView);
o imgPhoto = (ImageView)itemView.findViewById(R.id.img_item
_photo);
o }
o }
o }
 Setelah semuanya selesai mari kita pasang lagi di MainActivity dengan
menambahkan satu method berikut :
o private void showRecyclerGrid(){
o rvCategory.setLayoutManager(new GridLayoutManager(this, 2));
o GridPresidentAdapter gridPresidentAdapter = new GridPresidentAdap
ter(this);
o gridPresidentAdapter.setListPresident(list);
o rvCategory.setAdapter(gridPresidentAdapter);
o }

Dan lengkapi method onOptionItemSelected() menjadi seperti berikut :

o @Override
o public boolean onOptionsItemSelected(MenuItem item) {
o switch (item.getItemId()){
o case R.id.action_list:
o showRecyclerList();
o break;
o case R.id.action_grid:
o showRecyclerGrid();
o break;
o case R.id.action_cardview:
o break;
o }
o return super.onOptionsItemSelected(item);
o }
 Ini akan update tampilan ketika id dari action menu yang dipilih ditekan oleh
pengguna. Sekarang coba jalankan lagi aplikasi anda, maka sekarang anda
sudah bisa menampilkan dua bentuk dari RecyclerView yaitu list dan grid.
Yeay!!


1. Tinggal satu lagi, ayo kita lanjutkan dengan membuat
bentuk RecyclerView dengan komponen CardView.
Penggunaan CardView merupakan salah satu pattern yang direkomendasikan
pada pendekatan MaterialDesignyang dimana item-item pada koleksi data
ditampilkan dengan bungkusan layaknya sebuah kartu. Penggunaan
pendekatan hanya diperuntukkan jika dalam item list tersebut memiliki lebih
dari satu action. Baik, buat kembali file layout
xml item_cardview_president dan lengkapi kodenya menjadi seperti berikut :

1. <?xml version="1.0" encoding="utf-8"?>


2. <android.support.v7.widget.CardView
3. xmlns:android="http://schemas.android.com/apk/res/android"
4. xmlns:card_view="http://schemas.android.com/apk/res-auto"
5. android:id="@+id/card_view"
6. android:layout_gravity="center"
7. android:layout_width="match_parent"
8. android:layout_height="wrap_content"
9. android:layout_marginTop="4dp"
10. android:layout_marginBottom="4dp"
11. android:layout_marginLeft="8dp"
12. android:layout_marginRight="8dp"
13. card_view:cardCornerRadius="4dp">
14. <RelativeLayout
15. android:layout_width="match_parent"
16. android:layout_height="200dp"
17. android:padding="8dp">
18. <ImageView
19. android:layout_width="150dp"
20. android:layout_height="220dp"
21. android:scaleType="centerCrop"
22. android:id="@+id/img_item_photo"
23. android:layout_marginBottom="4dp"/>
24. <TextView
25. android:layout_toRightOf="@id/img_item_photo"
26. android:id="@+id/tv_item_name"
27. android:layout_width="match_parent"
28. android:layout_height="wrap_content"
29. android:textSize="16sp"
30. android:textStyle="bold"
31. android:text="Name"
32. android:layout_marginTop="@dimen/activity_vertical_margin"
33. android:layout_marginBottom="8dp"
34. android:layout_marginRight="@dimen/activity_vertical_margin"
35. android:layout_marginLeft="@dimen/activity_vertical_margin"/>
36. <TextView
37. android:layout_below="@id/tv_item_name"
38. android:layout_toRightOf="@id/img_item_photo"
39. android:id="@+id/tv_item_remarks"
40. android:layout_width="match_parent"
41. android:layout_height="wrap_content"
42. android:text="Remarks"
43. android:layout_marginBottom="8dp"
44. android:layout_marginRight="@dimen/activity_vertical_margin"
45. android:layout_marginLeft="@dimen/activity_vertical_margin"/>
46. <LinearLayout
47. android:layout_width="match_parent"
48. android:layout_height="wrap_content"
49. android:layout_alignParentBottom="true"
50. android:layout_toRightOf="@id/img_item_photo"
51. android:layout_marginLeft="@dimen/activity_horizontal_margin"
52. android:orientation="horizontal">
53. <Button
54. android:id="@+id/btn_set_favorite"
55. android:layout_width="match_parent"
56. android:layout_height="wrap_content"
57. android:textSize="11sp"
58. style="@style/Widget.AppCompat.Button.Colored"
59. android:text="Favorite"
60. android:layout_weight="1"/>
61. <Button
62. android:id="@+id/btn_set_share"
63. android:layout_width="match_parent"
64. android:layout_height="wrap_content"
65. android:textSize="11sp"
66. style="@style/Widget.AppCompat.Button.Colored"
67. android:text="Share"
68. android:layout_weight="1"/>
69. </LinearLayout>
70. </RelativeLayout>
71. </android.support.v7.widget.CardView>
2. Setelah selesai, buat kembali kelas adapter dengan
nama CardViewPresidentAdapter dan lengkapi kodenya menjadi seperti
berikut :
1. public class CardViewPresidentAdapter extends RecyclerView.Adapter<Ca
rdViewPresidentAdapter.CardViewViewHolder>{
2. private ArrayList<President>listPresident;
3. private Context context;
4.
5. public CardViewPresidentAdapter(Context context) {
6. this.context = context;
7. }
8.
9. public ArrayList<President> getListPresident() {
10. return listPresident;
11. }
12.
13. public void setListPresident(ArrayList<President> listPresident)
{
14. this.listPresident = listPresident;
15. }
16. @Override
17. public CardViewViewHolder onCreateViewHolder(ViewGroup parent, in
t viewType) {
18. View view = LayoutInflater.from(parent.getContext()).inflate(
R.layout.item_cardview_president, parent, false);
19. CardViewViewHolder viewHolder = new CardViewViewHolder(view);
20. return viewHolder;
21. }
22.
23. @Override
24. public void onBindViewHolder(CardViewViewHolder holder, int posit
ion) {
25.
26. President p = getListPresident().get(position);
27.
28. Glide.with(context)
29. .load(p.getPhoto())
30. .override(350, 550)
31. .into(holder.imgPhoto);
32.
33. holder.tvName.setText(p.getName());
34. holder.tvRemarks.setText(p.getRemarks());
35.
36. holder.btnFavorite.setOnClickListener(new CustomOnItemClickLi
stener(position, new CustomOnItemClickListener.OnItemClickCallback()
{
37.
38. @Override
39. public void onItemClicked(View view, int position) {
40. Toast.makeText(context, "Favorite "+getListPresident(
).get(position).getName(), Toast.LENGTH_SHORT).show();
41. }
42. }));
43.
44. holder.btnShare.setOnClickListener(new CustomOnItemClickListe
ner(position, new CustomOnItemClickListener.OnItemClickCallback() {
45.
46. @Override
47. public void onItemClicked(View view, int position) {
48. Toast.makeText(context, "Share " + getListPresident()
.get(position).getName(), Toast.LENGTH_SHORT).show();
49. }
50. }));
51. }
52.
53. @Override
54. public int getItemCount() {
55. return getListPresident().size();
56. }
57.
58. public class CardViewViewHolder extends RecyclerView.ViewHolder{
59. ImageView imgPhoto;
60. TextView tvName, tvRemarks;
61. Button btnFavorite, btnShare;
62. public CardViewViewHolder(View itemView) {
63. super(itemView);
64. imgPhoto = (ImageView)itemView.findViewById(R.id.img_item
_photo);
65. tvName = (TextView)itemView.findViewById(R.id.tv_item_nam
e);
66. tvRemarks = (TextView)itemView.findViewById(R.id.tv_item_
remarks);
67. btnFavorite = (Button)itemView.findViewById(R.id.btn_set_
favorite);
68. btnShare = (Button)itemView.findViewById(R.id.btn_set_sha
re);
69. }
70. }
71. }
3. Untuk handle ketika dua tombol yang kita miliki diklik silakan buat kelas baru
dengan nama CustomOnItemClickListener dan lengkapi kodenya menjadi
seperti berikut :

1. public class CustomOnItemClickListener implements View.OnClickListene


r {
2. private int position;
3. private OnItemClickCallback onItemClickCallback;
4. public CustomOnItemClickListener(int position, OnItemClickCallbac
k onItemClickCallback) {
5. this.position = position;
6. this.onItemClickCallback = onItemClickCallback;
7. }
8.
9. @Override
10. public void onClick(View view) {
11. onItemClickCallback.onItemClicked(view, position);
12. }
13. public interface OnItemClickCallback {
14. void onItemClicked(View view, int position);
15. }
16. }
4. Setelah selesai, kita menambahkan satu method lagi untuk menampilkan
bentuk RecyclerView ini dengan melengkapi kode
pada MainActivity menjadi seperti berikut:
1. private void showRecyclerCardView(){
2. rvCategory.setLayoutManager(new LinearLayoutManager(this));
3. CardViewPresidentAdapter cardViewPresidentAdapter = new CardViewP
residentAdapter(this);
4. cardViewPresidentAdapter.setListPresident(list);
5. rvCategory.setAdapter(cardViewPresidentAdapter);
6. }

Dan update method onOptionItemSelected() menjadi seperti berikut :

7. @Override
8. public boolean onOptionsItemSelected(MenuItem item) {
9.
10. switch (item.getItemId()){
11. case R.id.action_list:
12. showRecyclerList();
13. break;
14.
15. case R.id.action_grid:
16. showRecyclerGrid();
17. break;
18.
19. case R.id.action_cardview:
20. showRecyclerCardView();
21. break;
22. }
23. return super.onOptionsItemSelected(item);
24. }
5. Jalankan aplikasinya dan seharusnya anda sudah bisa menampilkan tiga
bentuk RecyclerView yang telah kita diskusikan di awal. Mantap!
6. Untuk mempercantik tampilan dan menyesuaikan dengan target yang di awal,
kita akan melakukan penambahan method untuk mengubah judul halaman
setiap kita melakukan perubahan bentuk dari RecyclerView.
1. private void setActionBarTitle(String title){
2. getSupportActionBar().setTitle(title);
3. }

Dan kita update kembali method onOptionItemSelected() sehingga menjadi


seperti berikut :

4. @Override
5. public boolean onOptionsItemSelected(MenuItem item) {
6. String title = null;
7. switch (item.getItemId()){
8. case R.id.action_list:
9. title = "Mode List";
10. showRecyclerList();
11. break;
12. case R.id.action_grid:
13. showRecyclerGrid();
14. title = "Mode Grid";
15. break;
16.
17. case R.id.action_cardview:
18. title = "Mode CardView";
19. showRecyclerCardView();
20. break;
21. }
22. setActionBarTitle(title);
23. return super.onOptionsItemSelected(item);
24. }

Dan pada method onCreate() tambahkan baris ini setActionBarTitle("Mode


List"); Sebelum kita memanggil method showRecyclerList();

7. Jalankan kembali aplikasinya dan sekarang ketika anda berpindah dari satu
bentuk RecyclerView ke bentuk yang lain maka tiap itu pula terjadi perubahan
judul. Keren euy!
1. Tidak seperti ListView yang memiliki listener untuk melakukan sebuah aksi
ketika salah satu item pada list dipilih. Pada RecyclerView kita harus
membuatnya secara manual.
Namun tenang kami akan menunjukan bagaimana caranya menghandle
ketika salah satu item pada list di RecyclerView dipilih.
Pertama buat file bernama ids pada direktori values. Klik kanan pada values
→ new → Value resource file dan isikan ids pada field file name.
Setelah terbentuk lengkapi kodenya menjadi seperti berikut :

1. <?xmlversion="1.0" encoding="utf-8"?>
2. <resources>
3. <item name="item_click_support"type="id" />
4. </resources>
2. Selanjutnya buat kelas baru dengan nama ItemClickSupport dan lengkapi
kodenya menjadi seperti berikut :
1. public class ItemClickSupport {
2. private final RecyclerView mRecyclerView;
3. private OnItemClickListener mOnItemClickListener;
4. private OnItemLongClickListener mOnItemLongClickListener;
5.
6. private ItemClickSupport(RecyclerView recyclerView) {
7. mRecyclerView = recyclerView;
8. mRecyclerView.setTag(R.id.item_click_support, this);
9. mRecyclerView.addOnChildAttachStateChangeListener(mAttachLis
tener);
10. }
11.
12. private View.OnClickListener mOnClickListener = new View.OnClick
Listener() {
13.
14. @Override
15. public void onClick(View v) {
16. if (mOnItemClickListener != null) {
17. RecyclerView.ViewHolder holder = mRecyclerView.getCh
ildViewHolder(v);
18. mOnItemClickListener.onItemClicked(mRecyclerView, ho
lder.getAdapterPosition(), v);
19. }
20. }
21. };
22. private View.OnLongClickListener mOnLongClickListener = new View
.OnLongClickListener() {
23.
24. @Override
25. public boolean onLongClick(View v) {
26. if (mOnItemLongClickListener != null) {
27. RecyclerView.ViewHolder holder = mRecyclerView.getCh
ildViewHolder(v);
28. return mOnItemLongClickListener.onItemLongClicked(mR
ecyclerView, holder.getAdapterPosition(), v);
29. }
30. return false;
31. }
32. };
33. private RecyclerView.OnChildAttachStateChangeListener mAttachLis
tener
34. = new RecyclerView.OnChildAttachStateChangeListener() {
35.
36. @Override
37. public void onChildViewAttachedToWindow(View view) {
38. if (mOnItemClickListener != null) {
39. view.setOnClickListener(mOnClickListener);
40. }
41. if (mOnItemLongClickListener != null) {
42. view.setOnLongClickListener(mOnLongClickListener);
43. }
44. }
45.
46. @Override
47. public void onChildViewDetachedFromWindow(View view) {
48. }
49. };
50. public static ItemClickSupport addTo(RecyclerView view) {
51. ItemClickSupport support = (ItemClickSupport) view.getTag(R.
id.item_click_support);
52. if (support == null) {
53. support = new ItemClickSupport(view);
54. }
55. return support;
56. }
57. public static ItemClickSupport removeFrom(RecyclerView view) {
58. ItemClickSupport support = (ItemClickSupport) view.getTag(R.
id.item_click_support);
59. if (support != null) {
60. support.detach(view);
61. }
62. return support;
63. }
64. public ItemClickSupport setOnItemClickListener(OnItemClickListen
er listener) {
65. mOnItemClickListener = listener;
66. return this;
67. }
68. public ItemClickSupport setOnItemLongClickListener(OnItemLongCli
ckListener listener) {
69. mOnItemLongClickListener = listener;
70. return this;
71. }
72. private void detach(RecyclerView view) {
73. view.removeOnChildAttachStateChangeListener(mAttachListener)
;
74. view.setTag(R.id.item_click_support, null);
75. }
76. public interface OnItemClickListener {
77. void onItemClicked(RecyclerView recyclerView, int position,
View v);
78. }
79. public interface OnItemLongClickListener {
80. boolean onItemLongClicked(RecyclerView recyclerView, int pos
ition, View v);
81. }
82. }
Pada prinsipnya kelas ItemClickSupport akan menjadi satu kelas handler
untuk melakukan action ketika pengguna menekan atau melakukan klik yang
lama (long clicked) terhadap salah satu item pada RecyclerView.
3. Setelah selesai, mari kita pasang pada MainActivity dan tambahkan satu
method ini untuk menandakan item mana yang dipilih.
1. private void showSelectedPresident(President president){
2. Toast.makeText(this, "Kamu memilih "+president.getName(), Toast.
LENGTH_SHORT).show();
3. }

Dan tambahkan pada masing-masing method di list dan grid seperti berikut :

4. private void showRecyclerList(){


5. rvCategory.setLayoutManager(new LinearLayoutManager(this));
6. ListPresidentAdapter listPresidentAdapter = new ListPresidentAda
pter(this);
7. listPresidentAdapter.setListPresident(list);
8. rvCategory.setAdapter(listPresidentAdapter);
9.
10. ItemClickSupport.addTo(rvCategory).setOnItemClickListener(new It
emClickSupport.OnItemClickListener() {
11. @Override
12. public void onItemClicked(RecyclerView recyclerView, int position, V
iew v) {
13. showSelectedPresident(list.get(position));
14. }
15. });
16. }
17.
18. private void showRecyclerGrid(){
19. rvCategory.setLayoutManager(new GridLayoutManager(this, 2));
20. GridPresidentAdapter gridPresidentAdapter = new GridPresidentAda
pter(this);
21. gridPresidentAdapter.setListPresident(list);
22. rvCategory.setAdapter(gridPresidentAdapter);
23.
24. ItemClickSupport.addTo(rvCategory).setOnItemClickListener(new It
emClickSupport.OnItemClickListener() {
25. @Override
26. public void onItemClicked(RecyclerView recyclerView, int position, V
iew v) {
27. showSelectedPresident(list.get(position));
28. }
29. });
30. }
4. Sekarang jalankan kembali aplikasi kamu dan coba kamu klik salah satu item
pada RecyclerView bentuk list dan grid seharusnya akan menampilkan
sebuah obyek Toast terhadap item yang ditekan.
Selesai! Sampai saat ini kamu telah berhasil mengimplementasikan beragam bentuk
dari RecyclerView dan mudah bukan?
Ini akan sangat penting sekali karena ke depannya pasti kamu akan berhadapan
dengan koleksi data yang harus ditampilkan ke dalam bentuk list.
Dan selamat kamu sudah belajar banyak sejauh ini.

Bedah Kode

Pendekatan umum dalam mengembangkan aplikasi mobile terletak pada bentuk list
to detail dengan artian menampilkan sejumlah informasi dalam bentuk list dan
kemudian pengguna melakukan klik untuk mendapatkan detail informasi pada item
pada list yang dipilih.

Pendekatan tersebut sangat lumrah dikarenakan keterbatasan besar layar yang


menjadikan penggunaan dua jempol pada tangan pengguna sebagai pointer untuk
melakukan sebuah aksi pada aplikasi.
Android sendiri memiliki dua mekanisme penampilan data dalam jumlah yang
banyak yaitu dalam bentuk ListView, GridView, maupun RecyclerView. Namun
semenjak direkomendasikan sebuah pendekatan desain
bernama Material Design para developer dituntut untuk memahami suksesor dari
komponen ListView ini.
Kelebihan dari RecyclerView terletak pada banyak hal namun dititikberatkan pada
performa dan fleksibilitasnya.
Pada sisi performa, secara default adapter dari RecyclerView harus lah
mengimplementasikan ViewHolder pattern. Dimana ini adalah pendekatan tentang
bagaimana sebuah tampilan item list diciptakan, dipertahankan, dan dihancurkan
dari memori. Tujuan dari pendekatan ini adalah bahwa RecyclerView akan tetap
responsif dengan mempertahankan peforma terbaik ketika menampilkan koleksi
data dalam jumlah yang banyak. Ini jelas berbeda dengan ListView yang tidak
mewajibkan pattern tersebut secara default. Pada salah satu contoh adapter yang
kita tuliskan di atas, pattern ViewHolder diimplementasikan pada bagian berikut :

1. @Override
2. public CategoryViewHolder onCreateViewHolder(ViewGroup parent, int viewType
) {
3. View itemRow = LayoutInflater.from(parent.getContext()).inflate(R.layou
t.item_row_president, parent, false);
4. return new CategoryViewHolder(itemRow);
5. }
6.
7. @Override
8. public void onBindViewHolder(CategoryViewHolder holder, int position) {
9. holder.tvName.setText(getListPresident().get(position).getName());
10. holder.tvRemarks.setText(getListPresident().get(position).getRemarks())
;
11.
12. Glide.with(context)
13. .load(getListPresident().get(position).getPhoto())
14. .override(55, 55)
15. .crossFade()
16. .into(holder.imgPhoto);
17. }
18.
19. class CategoryViewHolder extends RecyclerView.ViewHolder{
20. TextView tvName;
21. TextView tvRemarks;
22. ImageView imgPhoto;
23.
24. public CategoryViewHolder(View itemView) {
25. super(itemView);
26. tvName = (TextView)itemView.findViewById(R.id.tv_item_name);
27. tvRemarks = (TextView)itemView.findViewById(R.id.tv_item_remarks);
28. imgPhoto = (ImageView)itemView.findViewById(R.id.img_item_photo);
29. }
30. }

Setiap kali kita melakukan scroll pada RecyclerView secara


otomatis RecyclerView akan mengecek ke memori apakah obyek item view pada
indeks tertentu sudah berada di memori atau belum. Jika belum maka akan
dilakukan sebuah proses casting view (findViewById) yang berharga sangat mahal
di memori dengan dijalankannya
method onCreateViewHolder(). Method onBindViewHolder() berperan sebagai
method yang akan menampilkan koleksi data dalam format tampilan yang
ditentukan; baris per baris jika pada bentuk list atau baris dan kolom pada bentuk
grid. Hubungan antara satu adapter dengan ViewHolder adalah satu ke banyak
dengan artian satu kelas adapter bisa memiliki lebih dari satu ViewHolder.

1. rvCategory.setHasFixedSize(true);

Menjelaskan bahwa jika kita set nilai true, RecyclerView secara otomatis dapat
melakukan optimasi untuk ukuran lebar dan tinggi RecyclerView adalah konstan.
Terlebih jika kita memiliki koleksi data yang dinamis untuk proses penambahan,
perpindahan, dan pengurangan item dari koleksi data.
Kita menggunakan library keren bernama Glide untuk menampilkan foto dari URL
yang diberikan secara asynchronous.
Pada sisi fleksibilitas, RecyclerView memiliki beragam bentuk yang disesuaikan
dengan design yang diinginkan, kita hanya perlu set nilai pada
method setLayoutManager() saja untuk menentukan
bagaimana RecyclerViewditampilkan.

1. rvCategory.setLayoutManager(new LinearLayoutManager(this));

atau

1. rvCategory.setLayoutManager(new GridLayoutManager(this, 2));

Terakhir, untuk membuat kamu lebih paham tentang RecyclerView beberapa link di
bawah ini wajib kamu baca :

 RecylerView
 Using the RecyclerView
 Fundamentals for ListView
 RecyclerView Animator