Dasar-dasar Pembuatan Layout Aplikasi Android dengan XML

Bagus Aji Santoso 21 Agustus 2017

Dasar-dasar Pembuatan Layout Aplikasi Android dengan XML

Pendahuluan

Layout View adalah sebuah tipe kelas View dengan tujuan khusus untuk mengorganisir dan memposisikan view-view lain di dalamnya (contohnya adalah LinearLayout, RelativeLayout, dll.)

Activity di Android menggunakan layout sebagai container untuk view lain di dalamnya, bahkan juga bisa berisi layout lain. Container layout di hampir semua Activity Android bekerja dengan cara yang mirip dengan elemen "div" di HTML.

Layout yang paling umum dipakai diantaranya adalah LinearLayout, RelativeLayout, dan FrameLayout.

Sangat penting untuk memahami hirarki dari suatu Layout. Setiap layout merupakan subclass dari ViewGroup yang juga subclass dari kelas View. ViewGroup memiliki nested static class bernama LayoutParams yang dipakai untuk membuat atau mengubah layout melalui kode Java. Oleh karena itu subclass dari ViewGroup seperti LinearLayout, memiliki kelas LayoutParams sendiri-sendiri yang dapat diakses lewat ViewGroup.LayoutParams.

LinearLayout

Sebuah linear layout, sesuai dengan namanya menampilkan dan memposisikan elemen di dalamnya dalam satu arah, secara horizontal atau vertikal. Arahnya dapat diatur melalui atribut android:orientation.

Semua isi dari LinearLayout akan ditampilkan berdasarkan urutan penulisan mereka di file layout. Beberapa atribut yang sering dipakai dalam suatu LinearLayout adalah:

  • android:gravity - Mengontrol penjajaran konten dari suatu view (seperti text-align di CSS)
  • android:layout_gravity - Mengontrol penjajaran view di dalam suatu container (seperti float di CSS)
  • android:layout_weight - Menentukan berapa lebar atau tinggi ruang ekstra untuk diberikan pada suatu view.

Contoh kode LinearLayout:

<?xml version="1.0" encoding="utf-8"?> <!-- Parent linear layout with vertical orientation --> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Email:" android:padding="5dp"/> <EditText android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginBottom="10dp"/> </LinearLayout>

Distribusi Tinggi/Lebar View dengan Layout Weight

Jika ingin membuat misalnya sebuah layout yang memiliki tiga Button dengan lebar yang sama, atau ingin membuat map mengambil jatah 4/5 layar dan 1/5 diberikan ke komponen lain di bawahnya), LinearLayout dapat kita pakai. Triknya ialah dengan menggunakan android:layout_weight.

Pertama, kita perlu menentukan android:weightSum untuk menentukan jumlah total (di LinearLayout-nya) dan android:layout_weight di masing-masing view di dalam LinearLayout untuk menentukan jatah ruang yang didapatkan.

<LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" android:weightSum="5" android:layout_alignParentBottom="true"> <ImageButton android:id="@+id/btnLocEnable" android:src="@drawable/ic_location" android:layout_width="0dp" android:layout_weight="2" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:background="@color/twitter_light_blue" /> <ImageButton android:id="@+id/btnUploadPhoto" android:src="@drawable/ic_addimage" android:layout_width="0dp" android:layout_weight="3" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:background="@color/twitter_light_blue"/> </LinearLayout>

Dengan XML di atas, btnLocEnable akan mengambil 2/5 dari lebar container (dalam hal ini LinearLayout-nya) dan btnUploadPhoto akan mengambil jatah 3/5.

RelativeLayout

Dalam sebuah RelativeLayout, kita memposisikan view di dalamnya relatif terhadap view lain atau si parent view-nya. Atribut yang bisa dipakai untuk memposisikan suatu View di dalam RelativeLayout adalah:

  • Posisi berdasarkan View lain yang satu level: layout_above, layout_below, layout_toLeftOf, layout_toRightOf
  • Posisi berdasarkan parent: android:layout_centerHorizontal, android:layout_centerVertical
  • Posisi penjajaran berdasarkan View lain yang satu level: layout_alignTop, layout_alignBottom, layout_alignLeft, layout_alignRight, layout_alignBaseline
  • Posisi penjajaran berdasarkan parent: layout_alignParentTop, layout_alignParentBottom, layout_alignParentLeft, layout_alignParentRight

Contoh Relativelayout:

<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content"> <TextView android:id="@+id/label" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Email" /> <EditText android:id="@+id/inputEmail" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_below="@id/label" /> <Button android:id="@+id/btnLogin" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/inputEmail" android:layout_alignParentLeft="true" android:layout_marginRight="5dp" android:text="Login" /> </RelativeLayout>

Menggunakan Penjajaran Untuk Menentukan Lebar atau Tinggi View

Aspek RelativeLayout yang jarang dipahami adalah menggunakan penjajaran untuk menentukan tinggi atau lebar suatu View. Dibagian ini kita membahas bagaimana memanfaatkan RelativeLayout dan menentukan tinggi lebar suatu View secara dinamis.

Contoh 1: Menentukan Lebar

Misal kita memiliki sebuah layout yang seperti ini:

Image

Kode XML untuk layout di atas:

<RelativeLayout 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:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity"> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="1245678901234567890" android:id="@+id/button1"/> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="CANCEL IT" android:id="@+id/button2" android:layout_below="@id/button1" android:layout_alignLeft="@id/button1" /> </RelativeLayout>

Anggap kita ingin agar tombol kedua sejajar di sebelah kiri dan sebelah kanan tombol pertama sekaligus. Jika kita tambahkan android:layout_alignRight="@id/button1" ke kode XML tombol kedua, maka penambahan kode ini akan membuat tombol pertama mengubah lebarnya agar dapat membuatnya sejajar dengan posisi sebelah kanan tombol pertama.

Image

Dengan ini dapat kita simpulkan bahwa untuk membuat suatu view agar memiliki lebar yang sama dengan view lain kita harus membuat ia sejajar di sisi sebelah kiri maupun kanan sekaligus.

Contoh 2: Menentukan Tinggi

Misal kita memiliki kode layout XML seperti berikut ini:

<RelativeLayout 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:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity">

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:height="200dp"
        android:text="1245678901234567890"
        android:id="@+id/button1"/>

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="CANCEL IT"
        android:id="@+id/button2"
        android:layout_toRightOf="@id/button1" />
</RelativeLayout> 

Hasilnya akan menjadi:

Image

Jika ingin agar tombol Cancel It memiliki tinggi yang sama dengan tombol yang pertama, kita dapat menentukan layout_alignTop dan layout_alignBottom di tombol yang kedua.

<Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignTop="@id/button1" android:layout_alignBottom="@id/button1" android:text="CANCEL IT" android:id="@+id/button2" android:layout_toRightOf="@id/button1" />

Maka layout baru yang akan kita dapatkan menjadi:

Image

PercentRelativeLayout

PercentRelativeLayout adalah tambahan baru di Design Support Library. Layout ini memperbolehkan suatu view selain memiliki posisi yang relatif dengan view lain dia juga dapat mengambil persentase dari ruang yang tersedia. Sebelum ini jika menginginkan dua elemen berada sejajar dengan tinggi/lebar yang sama, maka kita biasanya menggunakan LinearLayout di dalam sebuah RelativeLayout. PercentRelativeLayout dibuat untuk menyelesaikan permasalahan semacam ini.

Image

Untuk menggunakan Layout ini kita harus menambahkan dependensi Gradle terlebih dahulu. Samakan isi X.X.X dengan nomor versi Design Support Library yang lain.

dependencies { compile "com.android.support:percent:X.X.X" }

Atribut layout_width dan layout_height dari PercentRelativeLayout harus menentukan jumlah tinggi dan lebar yang dapat dipakai. View-view yang ditambahkan didalamnya harus menentukan tinggi dan lebar menggunakan layout_heightPercent dan/atau layout_widthPercent. Karena PercentRelativeLayout tidak termasuk ke dalam pustaka standar Android, kita harus menggunakan namespace app.

Contoh kode PercenteRelativeLayout untuk menghasilkan gambar di atas adalah sebagai berikut:

<android.support.percent.PercentRelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent"> <View android:id="@+id/top_left" android:layout_width="0dp" android:layout_height="0dp" android:layout_alignParentTop="true" android:background="#ff44aacc" app:layout_heightPercent="20%" app:layout_widthPercent="70%" /> <View android:id="@+id/top_right" android:layout_width="0dp" android:layout_height="0dp" android:layout_alignParentTop="true" android:layout_toRightOf="@+id/top_left" android:background="#ffe40000" app:layout_heightPercent="20%" app:layout_widthPercent="30%" /> <View android:id="@+id/bottom" android:layout_width="match_parent" android:layout_height="0dp" android:layout_below="@+id/top_left" android:background="#ff00ff22" app:layout_heightPercent="80%" /> </android.support.percent.PercentRelativeLayout>

Contoh-contoh lainnya dapat dilihat di:

Persentase Margin

Kita juga dapat memberikan margin dengan persentase:

  • app:layout_marginStartPercent
  • app:layout_marginEndPercent
  • app:layout_marginTopPercent
  • app:layout_marginBottomPercent
  • app:layout_marginPercent

Aspek Rasio

Dengan mengatur salah satu tinggi atau lebarnya menjadi 0dp, atribut app:layout_aspectRatio dapat menentukan rasio tinggi lebarnya secara dinamis:

<android.support.percent.PercentRelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:background="#ff00ff22" android:layout_width="match_parent" android:layout_height="match_parent"> <!-- not using aspectRatio here --> <View android:id="@+id/view1" android:background="#ff44aacc" android:layout_width="300dp" android:layout_height="wrap_content" app:layout_heightPercent="50%"/> <!-- using aspectRatio here --> <View android:layout_below="@id/view1" android:background="#ffe40000" android:layout_width="300dp" android:layout_height="0dp" app:layout_aspectRatio="160%"/> </android.support.percent.PercentRelativeLayout>

Berikut ini hasilnya:

Image

FrameLayout

Dalam sebuah FrameLayout kita menampilkan isinya lewat z-index. Artinya, View paling akhir akan berada di atas View yang lain.

Contoh kode FrameLayout:

<?xml version="1.0" encoding="utf-8"?> <FrameLayout android:id="@+id/frame_layout" android:layout_width="match_parent" android:layout_height="match_parent" xmlns:android="http://schemas.android.com/apk/res/android"> <!-- Child1 is drawn first --> <ImageView android:id="@+id/child1" android:adjustViewBounds="true" android:scaleType="centerCrop" android:layout_width="match_parent" android:layout_height="match_parent" android:contentDescription="Image" android:src="@drawable/mosque" /> <!-- Child2 is drawn over Child1 --> <TextView android:id="@+id/child2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Child 2" android:layout_gravity="top|left" /> <!-- Child3 is drawn over Child1 and Child2 --> <TextView android:id="@+id/child3" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Child 3" android:layout_gravity="top|right" /> </FrameLayout>

Dicontoh ini kita membuat agar ImageView memenuhi ruang FrameLayout lalu kita tambahkan dua TextView di atasnya.

Image

Memahami View Layer

Dasar-dasar Layering

Saat dua view saling tumpang tindih, maka salah satu View akan hilang di belakang View yang lain. Urutan penapilan View akan mengikuti urutan mereka dituliskan di XML. Dengan demikian, view yang ada di paling bawah XML akan ditampilkan ke layar paling akhir menutupi view yang lain.

Hal ini dibahas didokumentasi resmi Android, How Android Draws:

The tree is largely recorded and drawn in order, with parents drawn before (i.e., behind) their children, with siblings drawn in the order they appear in the tree. If you set a background drawable for a View, then the View will draw it before calling back to its onDraw() method. The child drawing order can be overridden with custom child drawing order in a ViewGroup, and with setZ(float) custom Z values} set on Views.

Menumpuk Dua View

Untuk menumpuk dua buah View dan membuat salah satunya berada di atas, kita dapat gunakan RelativeLayout atau FrameLayout. Anggap kita memiliki dua buah gambar membuat salah satu gambar berada di atas yang lain. Dengan RelativeLayout kodenya adalah sebagai berikut:

<RelativeLayout android:layout_width="wrap_content" android:layout_height="wrap_content"> <!-- Back view should be first to be drawn first! --> <ImageView android:layout_width="match_parent" android:layout_height="wrap_content" android:adjustViewBounds="true" android:scaleType="fitXY" android:src="@drawable/back_image_beach" /> <!-- Front view should be last to be drawn on top! --> <!-- Use `centerInParent` to center the image in the container --> <!-- Use `elevation` to ensure placement on top (not required) --> <ImageView android:layout_width="250dp" android:layout_height="wrap_content" android:adjustViewBounds="true" android:elevation="10dp" android:layout_centerInParent="true" android:scaleType="fitXY" android:src="@drawable/airbnb_logo_front" /> </RelativeLayout>

Hasilnya adalah:

Image

Memaksa View Untuk Tampil Paling Atas

Kita dapat memaksa sebuah View untuk tampil paling atas dari tumpukan View lain menggunakan Java:

myView.bringToFront(); myViwe.invalidate();

**Catatan: ** Lihat contoh lebih detail di sini.

Optimasi Performa Layout

Agar Layout memiliki performa yang lebih baik, minimalkan jumlah layout yang diinstansiasi dan yang lebih penting kurangi layout di dalam layout saat memungkinkan. Hal ini juga yang menjadi alasan mengapa RelativeLayout lebih disarankan dibanding menggunakan LinearLayout di dalam LinearLayout. Berikut beberapa tips untuk mengoptimalkan performa layout:

  • Jangan gunakan LinearLayout di dalam LinearLayout terlalu dalam karena dapat memakan memori.
  • Kurangi LinearLayout bersarang dengan RelativeLayout sehingga mendapatkan hirarki layout menjadi lebih flat yang berakibat penggunaan memori menjadi lebih sedikit.
  • Kadang saat layout menjadi kompleks, ada beberapa komponen yang mungkin suatu saat tidak dipakai seperti progress indicator atau pesan undo. Kita dapat mengurangi penggunaan memori yang mempercepat rendering dengan memuat hanya saat mereka dibutuhkan.

Sumber:

Codepath