Pelajari konsep kunci FrameLayout — ViewGroup paling sederhana di Android SDK, dirancang untuk menempatkan satu elemen anak (biasanya) atau menumpuk beberapa elemen satu sama lain. FrameLayout berguna untuk kontainer placeholder, fragmen, indikator pemuatan, dan elemen latar depan. Ia tidak mengelola posisi anak — setiap elemen berikutnya digambar di atas elemen sebelumnya, dan posisinya ditentukan oleh layout_gravity (left, top, right, bottom, center). Skenario dasar dijelaskan di FrameLayout API Reference.
Poin utama
FrameLayout adalah ViewGroup paling sederhana di Android SDK, dirancang untuk memblokir area layar dan menampilkan satu view anak (atau menumpuk beberapa). Berbeda dengan LinearLayout (penempatan berurutan) dan RelativeLayout (penempatan relatif), FrameLayout tidak mengubah posisi anak — setiap child baru secara default ditempatkan di sudut kiri atas (0,0) dan digambar di atas yang sebelumnya.
FrameLayout muncul di API Level 1 dan tetap menjadi kontainer Android paling ringan: ia tidak menimpa onMeasure dengan logika kompleks dan melakukan jumlah operasi layout minimum. Menurut Android Performance Blog, FrameLayout menjalankan onLayout dalam satu lintasan dan praktis tidak menambah overhead dibandingkan dengan penempatan View langsung. Ini menjadikannya pilihan ideal untuk kontainer yang mengutamakan kecepatan: layout item RecyclerView (dipasangkan dengan ConstraintLayout untuk penentuan posisi), kontainer fragmen, lapisan overlay.
Ukuran default FrameLayout ditentukan oleh elemen anak terbesar (jika match_parent tidak diatur). Jika tidak ada child yang ditentukan, FrameLayout menyusut ke (0,0). Atribut android:measureAllChildren (bagian di bawah) mengubah perilaku ini.
FrameLayout mewarisi ViewGroup dan merupakan induk langsung dari banyak kontainer khusus: FragmentContainerView (fragmen), CardView (kartu dengan bayangan), ScrollView (dengan satu child), NestedScrollView. Saat membuat Activity dengan navigasi Fragment, template standar Android Studio menggunakan FrameLayout (atau FragmentContainerView) sebagai kontainer utama untuk fragmen.
android:foreground — atribut FrameLayout yang menentukan drawable yang digambar di atas semua elemen anak. Berbeda dengan background (di bawah anak), foreground ditampilkan di atas konten dan bisa transparan. Digunakan untuk: efek overlay saat ditekan (ripple melalui ?attr/selectableItemBackground), masking gambar, menampilkan indikator status (centang pilihan di atas gambar).
Foreground mendukung sumber daya drawable standar: ColorDrawable, ShapeDrawable, RippleDrawable, LayerDrawable. Sejak API 23+, android:foregroundGravity tersedia untuk menempatkan foreground (fill, center, top, bottom). Dalam mode "isi" (fill), foreground diregangkan ke seluruh FrameLayout; dalam mode center — digambar di tengah.
android:measureAllChildren — atribut boolean (default true) yang menentukan apakah semua elemen anak perlu diukur saat menghitung ukuran FrameLayout. Jika true (default), FrameLayout memperhitungkan ukuran semua anak, termasuk GONE (dengan ukuran 0). Jika false, FrameLayout hanya mengukur anak VISIBLE dan INVISIBLE — elemen GONE dikecualikan dari perhitungan. Menurut Google I/O 2019, menonaktifkan measureAllChildren untuk kontainer dengan banyak elemen GONE (misalnya daftar dengan perpindahan visibilitas) mempercepat rendering awal 20–60%.
android:layout_gravity — atribut elemen anak FrameLayout (dan ViewGroup lainnya) yang menentukan posisinya di dalam kontainer. Di FrameLayout, layout_gravity adalah satu-satunya cara mengontrol posisi elemen anak, karena FrameLayout tidak menyediakan aturan penentuan posisi sendiri (seperti RelativeLayout) atau arah (seperti LinearLayout).
Nilai yang mungkin: top, bottom, left, right, center, center_horizontal, center_vertical, fill, fill_horizontal, fill_vertical, clip_horizontal, clip_vertical. Dikombinasikan dengan |: android:layout_gravity="bottom|center_horizontal" — elemen ditempelkan ke tepi bawah dan dipusatkan secara horizontal. Untuk elemen yang ukurannya lebih kecil dari FrameLayout, layout_gravity menentukan posisinya di ruang kosong.
Jika layout_gravity tidak diatur, secara default elemen ditempatkan di sudut kiri atas (top|left). Untuk FrameLayout yang berisi beberapa anak, masing-masing dapat memiliki layout_gravity sendiri — satu elemen bisa di sudut kiri atas, yang lain di sudut kanan bawah, yang ketiga di tengah. Ini memungkinkan pembuatan overlay sederhana (misalnya, tanda silang tutup di atas gambar).
android:gravity (atribut induk) meratakan konten di dalam FrameLayout — misalnya, teks di dalam TextView. android:layout_gravity (atribut anak) meratakan elemen itu sendiri di dalam FrameLayout. Dalam konteks FrameLayout, gravity menentukan bagaimana anak-anak diatur secara default (analog dengan layout_gravity untuk semua anak sekaligus), tetapi layout_gravity setiap elemen tertentu menimpa nilai induk.
Gambar dan label teks di sudut kanan bawah. FrameLayout berisi ImageView layar penuh dan TextView dengan layout_gravity="bottom|end" untuk penempatan di atas.
<FrameLayout
android:layout_width="match_parent"
android:layout_height="200dp">
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@drawable/product_photo"
android:scaleType="centerCrop" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_margin="8dp"
android:background="@drawable/badge_background"
android:elevation="2dp"
android:paddingHorizontal="8dp"
android:paddingVertical="4dp"
android:text="-30%"
android:textColor="@android:color/white"
android:textSize="14sp"
android:textStyle="bold" />
</FrameLayout>
ImageView menempati seluruh FrameLayout (tinggi 200dp). TextView dengan layout_gravity="bottom|end" ditempatkan di sudut kanan bawah di atas gambar. elevation=2dp menambahkan bayangan di bawah label, memisahkannya secara visual dari gambar. Ini adalah contoh minimal yang di LinearLayout memerlukan kontainer bersarang atau kode khusus.
Layar dengan konten dan progress bar di tengah yang muncul saat pemuatan. FrameLayout berisi dua elemen: konten dan ProgressBar dengan visibility="gone" (dialihkan dalam kode).
<FrameLayout
android:id="@+id/content_container"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/content_text"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:text="Konten yang dimuat"
android:textSize="18sp" />
<ProgressBar
android:id="@+id/loading_spinner"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_gravity="center"
android:visibility="gone" />
</FrameLayout>
ProgressBar secara default tersembunyi (gone). Saat memulai pemuatan, dalam kode dipanggil findViewById(R.id.loading_spinner).visibility = View.VISIBLE — spinner muncul di tengah di atas konten. Setelah pemuatan — .visibility = View.GONE. FrameLayout memastikan tumpukan tanpa mengubah posisi konten — teks tidak bergeser saat spinner muncul, karena ProgressBar digambar di atas.
FrameLayout sebagai kontainer standar untuk FragmentTransaction. Aktivitas mengganti fragmen di dalam kontainer ini tergantung pada navigasi.
<FrameLayout
android:id="@+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
import androidx.fragment.app.FragmentTransaction
val fragmentContainer = R.id.fragment_container
fun navigateTo(fragment: Fragment) {
supportFragmentManager
.beginTransaction()
.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE)
.replace(fragmentContainer, fragment)
.addToBackStack(null)
.commit()
}
FrameLayout sebagai kontainer fragmen — cara paling ringan untuk mendukung Fragment Navigation. FragmentContainerView (pewaris FrameLayout) direkomendasikan dengan Navigation Component 2.4+, tetapi FrameLayout sederhana tetap valid untuk FragmentTransaction manual. Keuntungan utama — FragmentTransaction.replace() sepenuhnya mengganti konten tanpa memengaruhi Activity.
FrameLayout optimal untuk empat skenario: kontainer fragmen (FragmentContainerView atau FrameLayout), overlay pemuatan (ProgressBar di atas konten), label kartu (tanda pada gambar), kontainer placeholder untuk ViewStub (pemuatan malas).
Tidak cocok untuk: penempatan kompleks beberapa elemen (gunakan ConstraintLayout), daftar berurutan (LinearLayout atau RecyclerView), tata letak dinamis dengan perubahan urutan elemen.
FrameLayout sebagai elemen root layar — praktik buruk jika layar berisi lebih dari 2–3 elemen. Untuk kontainer root gunakan ConstraintLayout — memberi lebih banyak kontrol atas penempatan tanpa kehilangan kinerja. Gunakan FrameLayout hanya untuk blok anak di mana diperlukan tumpukan atau placeholder.
Pertanyaan yang sering diajukan
FrameLayout — kontainer minimalis tanpa sistem penentuan posisi (hanya layout_gravity), dirancang untuk menumpuk elemen. ConstraintLayout — sistem tata letak lengkap dengan constraint, rantai, penghalang, ukuran persentase, dan dukungan MotionLayout. FrameLayout lebih cepat untuk kasus sederhana (1 child atau overlay); ConstraintLayout wajib untuk tata letak kompleks. Pilihan: FrameLayout untuk overlay pemuatan dan kontainer fragmen; ConstraintLayout untuk sisanya.
Atur ukuran FrameLayout menjadi wrap_content pada sumbu yang diinginkan (android:layout_width="wrap_content" dan/atau android:layout_height="wrap_content"). Dalam hal ini FrameLayout akan menyesuaikan dengan ukuran elemen anak terbesar. Jika semua anak lebih kecil dari FrameLayout, ruang berlebih akan tetap kosong. Untuk kontrol yang tepat, gunakan match_parent dengan padding tetap.
Ini adalah perilaku normal FrameLayout — ia tidak mendistribusikan anak di ruang, tetapi menggambarnya secara berurutan satu di atas yang lain. Jika Anda ingin elemen tidak saling tumpang tindih, gunakan kontainer lain (LinearLayout, ConstraintLayout). Untuk tumpang tindih sebagian dengan kontrol urutan gambar, gunakan layout_gravity untuk pergeseran dan elevation untuk Z-order.
FrameLayout lebih cepat untuk kasus yang sangat sederhana — satu elemen anak, tanpa penempatan kompleks. FrameLayout menjalankan onMeasure dalam waktu minimal, tanpa menghitung constraint. Namun perbedaannya hanya terlihat pada ratusan pengulangan (RecyclerView dengan puluhan ribu elemen). Untuk layar biasa (1–3 FrameLayout), perbedaannya dalam mikrodetik dan tidak memengaruhi UX. ConstraintLayout adalah pilihan universal untuk 95% tugas.
Ringkasan
Kami akan mengembangkan aplikasi seluler turnkey
IT Sectr membuat aplikasi iOS dan Android untuk startup dan bisnis sejak 2017. Kami akan memberi saran dan mengusulkan solusi terbaik.
Baca juga