FrameLayout: asosiy tushunchalar, Androidda oddiy joylashtirish

Muallif: IT Sectr Nashr etilgan: 2026-02-24 O'qish vaqti: 8 daq

FrameLayout — Android SDK-dagi eng oddiy ViewGroup bo'lib, odatda bitta bola elementini joylashtirish yoki bir nechta elementlarni bir-birining ustiga qo'yish uchun mo'ljallangan. FrameLayout placeholder konteynerlar, fragmentlar, yuklash indikatorlari va oldingi plan elementlari uchun qulaydir. U bolalarning joylashishini boshqarmaydi — har bir keyingi element oldingisining ustida chiziladi va ularning pozitsiyasi layout_gravity (left, top, right, bottom, center) orqali aniqlanadi. Asosiy stsenariylar FrameLayout API Reference-da tasvirlangan.

Asosiy fikrlar

  • Qatlamlarning ustma-ust qo'yilishi — FrameLayout elementlarni ketma-ket bir-birining ustiga joylashtiradi; XML-da eng oxirida e'lon qilingani hammadan yuqorida chiziladi.
  • Foreground — android:foreground atributi barcha bola elementlar ustiga drawable qo'yish imkonini beradi, effektlar va maskalash uchun foydali.
  • measureAllChildren — standart holatda FrameLayout hatto ko'rinmaydigan (GONE) bolalarni ham o'lchaydi. O'chirish renderlashni 20–60% tezlashtiradi.
  • layout_gravity — FrameLayout ichida bola elementini joylashtirishning yagona usuli: top, bottom, left, right, center.
  • Fragment bilan ishlatish — FrameLayout FragmentTransaction.replace() uchun standart konteyner bo'lib, faoliyatni qayta yaratmasdan tarkibni o'zgartiradi.

FrameLayout nima?

FrameLayout Android SDK-dagi eng oddiy ViewGroup bo'lib, ekran maydonini bloklash va bitta bola ko'rinishini (yoki bir nechtasini ustma-ust qo'yishni) ko'rsatish uchun mo'ljallangan. LinearLayout (ketma-ket joylashtirish) va RelativeLayout (nisbiy joylashtirish) dan farqli o'laroq, FrameLayout bolalarning pozitsiyasini o'zgartirmaydi — har bir yangi child standart bo'yicha yuqori chap burchakka (0,0) joylashtiriladi va oldingisining ustida chiziladi.

FrameLayout API Level 1 da paydo bo'lgan va Android-ning eng yengil konteyneri bo'lib qolmoqda: u onMeasure-ni murakkab mantiq bilan qayta yozmaydi va minimal miqdordagi layout operatsiyalarini bajaradi. Android Performance Blog'ga ko'ra, FrameLayout onLayout-ni bir o'tishda bajaradi va to'g'ridan-to'g'ri View joylashtirish bilan solishtirganda deyarli qo'shimcha yuk yaratmaydi. Bu uni tezlik muhim bo'lgan konteynerlar uchun ideal tanlovga aylantiradi: RecyclerView item-layoutlari (joylashtirish uchun ConstraintLayout bilan birga), Fragment konteynerlari, overlay qatlamlari.

FrameLayout-ning standart o'lchami eng katta bola elementi bilan aniqlanadi (agar match_parent o'rnatilmagan bo'lsa). Hech qanday child ko'rsatilmagan bo'lsa, FrameLayout (0,0) gacha yig'iladi. android:measureAllChildren atributi (quyidagi bo'lim) bu xatti-harakatni o'zgartiradi.

Android ViewGroup iyerarxiyasida FrameLayout

FrameLayout ViewGroup-dan meros oladi va ko'plab ixtisoslashtirilgan konteynerlarning to'g'ridan-to'g'ri ota-onasidir: FragmentContainerView (fragmentlar), CardView (soyali kartalar), ScrollView (bitta child bilan), NestedScrollView. Fragment navigatsiyasi bilan Activity yaratishda Android Studio-ning standart shabloni fragmentlar uchun asosiy konteyner sifatida FrameLayout (yoki FragmentContainerView) dan foydalanadi.

Foreground va measureAllChildren

android:foreground — barcha bola elementlar ustida chiziladigan drawable-ni belgilaydigan FrameLayout atributi. Background-dan (bolalar ostida) farqli o'laroq, foreground tarkibning ustida ko'rsatiladi va shaffof bo'lishi mumkin. Foydalaniladi: bosishdagi overlay effektlari (ripple ?attr/selectableItemBackground orqali), tasvirlarni maskalash, holat indikatorlarini ko'rsatish (tasvir ustida tanlash belgisi) uchun.

Foreground standart drawable resurslarini qo'llab-quvvatlaydi: ColorDrawable, ShapeDrawable, RippleDrawable, LayerDrawable. API 23+ dan boshlab foreground-ni joylashtirish uchun android:foregroundGravity (fill, center, top, bottom) mavjud. "To'ldirish" (fill) rejimida foreground butun FrameLayout bo'ylab cho'ziladi; center rejimida — markazda chiziladi.

android:measureAllChildren — FrameLayout o'lchamini hisoblashda barcha bola elementlarni o'lchash kerakligini aniqlaydigan mantiqiy atribut (standart true). Agar true (standart) bo'lsa, FrameLayout GONE (o'lchami 0) ni ham o'z ichiga olgan holda barcha bolalarning o'lchamlarini hisobga oladi. Agar false bo'lsa, FrameLayout faqat VISIBLE va INVISIBLE bolalarni o'lchaydi — GONE elementlari hisobdan chiqariladi. Google I/O 2019 ma'lumotlariga ko'ra, ko'p sonli GONE elementlari bo'lgan konteynerlar (masalan, ko'rinishi o'zgaradigan ro'yxatlar) uchun measureAllChildren-ni o'chirish dastlabki renderlashni 20–60% tezlashtiradi.

layout_gravity: FrameLayout ichida joylashtirish

android:layout_gravity — FrameLayout (va boshqa ViewGroup'lar) bola elementining konteyner ichidagi pozitsiyasini belgilaydigan atributidir. FrameLayout-da layout_gravity bola elementining joylashishini boshqarishning yagona usulidir, chunki FrameLayout o'ziga xos joylashtirish qoidalarini (RelativeLayout kabi) yoki yo'nalishni (LinearLayout kabi) taqdim etmaydi.

Mumkin bo'lgan qiymatlar: top, bottom, left, right, center, center_horizontal, center_vertical, fill, fill_horizontal, fill_vertical, clip_horizontal, clip_vertical. | bilan birlashtiriladi: android:layout_gravity="bottom|center_horizontal" — element pastki chetiga yopishtiriladi va gorizontal ravishda markazlashtiriladi. O'lchami FrameLayout-dan kichik bo'lgan elementlar uchun layout_gravity ularning bo'sh joydagi pozitsiyasini belgilaydi.

layout_gravity o'rnatilmagan bo'lsa, standart bo'yicha element yuqori chap burchakka (top|left) joylashtiriladi. Bir nechta bolasi bo'lgan FrameLayout-da har biri o'z layout_gravity-ga ega bo'lishi mumkin — bir element yuqori chap burchakda, boshqasi pastki o'ng burchakda, uchinchisi markazda bo'lishi mumkin. Bu oddiy ustma-ust qo'yishlarni yaratishga imkon beradi (masalan, tasvir ustida yopish xochi).

gravity va layout_gravity farqi

android:gravity (ota-ona atributi) FrameLayout ichidagi tarkibni tekislaydi — masalan, TextView ichidagi matn. android:layout_gravity (bola atributi) elementning o'zini FrameLayout ichida tekislaydi. FrameLayout kontekstida gravity bolalarning standart bo'yicha qanday joylashishini belgilaydi (barcha bolalar uchun layout_gravity analogi), lekin har bir elementning o'z layout_gravity-si ota-ona qiymatini bekor qiladi.

Misollar: XML va foydalanish holatlari

1-misol: Asosiy ustma-ust qo'yish — tasvir ustidagi yorliq

Tasvir va pastki o'ng burchakdagi matn yorlig'i. FrameLayout butun ekrandagi ImageView va ustiga joylashtirish uchun layout_gravity="bottom|end" bo'lgan TextView-ni o'z ichiga oladi.

xml
<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 butun FrameLayout-ni (200dp balandlik) egallaydi. layout_gravity="bottom|end" bo'lgan TextView tasvir ustida pastki o'ng burchakda joylashtiriladi. elevation=2dp yorliq ostiga soya qo'shib, uni tasvirdan vizual ravishda ajratadi. Bu LinearLayout-da ichki konteyner yoki maxsus kod talab qiladigan minimal misoldir.

2-misol: Yuklash indikatori (tarkib ustidagi progress bar)

Tarkib va yuklash paytida paydo bo'ladigan markazdagi progress bar bilan ekran. FrameLayout ikkita elementni o'z ichiga oladi: tarkib va visibility="gone" bo'lgan ProgressBar (kodda o'zgartiriladi).

xml
<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="Yuklangan tarkib"
        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 standart bo'yicha yashirin (gone). Yuklash boshlanganda kodda findViewById(R.id.loading_spinner).visibility = View.VISIBLE chaqiriladi — spinner tarkib ustida markazda paydo bo'ladi. Yuklash tugagandan so'ng — .visibility = View.GONE. FrameLayout tarkibning pozitsiyasini o'zgartirmasdan ustma-ust qo'yishni ta'minlaydi — ProgressBar ustida chizilgani uchun spinner paydo bo'lganda matn siljimaydi.

3-misol: Fragment konteyneri

FrameLayout FragmentTransaction uchun standart konteyner sifatida. Faoliyat navigatsiyaga qarab ushbu konteyner ichidagi fragmentlarni almashtiradi.

xml
<FrameLayout
    android:id="@+id/fragment_container"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />
kotlin
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 fragment konteyneri sifatida — Fragment Navigation-ni qo'llab-quvvatlashning eng yengil usuli. FragmentContainerView (FrameLayout-dan meros oluvchi) Navigation Component 2.4+ da tavsiya etiladi, ammo oddiy FrameLayout qo'lda FragmentTransaction uchun haqiqiy bo'lib qoladi. Asosiy afzallik — FragmentTransaction.replace() Activity-ga ta'sir qilmasdan tarkibni to'liq almashtiradi.

FrameLayout qachon ishlatilishi kerak

FrameLayout to'rtta stsenariy uchun optimaldir: fragment konteyneri (FragmentContainerView yoki FrameLayout), yuklash overlay-i (tarkib ustidagi ProgressBar), karta yorliqlari (tasvir ustidagi belgi), ViewStub uchun placeholder konteyner (dangasa yuklash).

Mos kelmaydi: bir nechta elementlarning murakkab joylashtirilishi (ConstraintLayout dan foydalaning), ketma-ket ro'yxatlar (LinearLayout yoki RecyclerView), elementlar tartibi o'zgaradigan dinamik layoutlar.

FrameLayout ekranning ildiz elementi sifatida — ekranda 2–3 dan ortiq element bo'lsa, yomon amaliyot. Ildiz konteyner uchun ConstraintLayout dan foydalaning — ishlashni yo'qotmasdan joylashtirish ustidan ko'proq nazorat beradi. FrameLayout-ni faqat ustma-ust qo'yish yoki placeholder kerak bo'lgan bola bloklari uchun ishlating.

Tez-tez beriladigan savollar

FrameLayout va ConstraintLayout o'rtasidagi farq nima?

FrameLayout — joylashtirish tizimisiz (faqat layout_gravity) minimalist konteyner, elementlarni ustma-ust qo'yish uchun mo'ljallangan. ConstraintLayout — konstraintlar, zanjirlar, to'siqlar, foiz o'lchamlari va MotionLayout qo'llab-quvvatlashi bilan to'liq layout tizimi. FrameLayout oddiy holatlar (1 child yoki overlay) uchun tezroq; ConstraintLayout murakkab maketlar uchun majburiy. Tanlov: FrameLayout yuklash overlay-i va fragment konteyneri uchun; ConstraintLayout qolgan hamma narsa uchun.

FrameLayout faqat eng katta child joyini egallashini qanday qilish mumkin?

Kerakli o'qda FrameLayout o'lchamini wrap_content qilib o'rnating (android:layout_width="wrap_content" va/yoki android:layout_height="wrap_content"). Bunday holda FrameLayout eng katta bola elementining o'lchamiga moslashadi. Agar barcha bolalar FrameLayout-dan kichik bo'lsa, ortiqcha bo'sh joy bo'sh qoladi. Aniq nazorat uchun sobit padding bilan match_parent dan foydalaning.

Nega FrameLayout-dagi elementlar bir-birini yopadi?

Bu FrameLayout-ning normal xatti-harakati — u bolalarni fazoda taqsimlamaydi, balki ularni ketma-ket bir-birining ustida chizadi. Agar elementlarning bir-birini yopmasligini istasangiz, boshqa konteynerdan (LinearLayout, ConstraintLayout) foydalaning. Chizish tartibini nazorat qilish bilan qisman yopish uchun siljitish uchun layout_gravity va Z-order uchun elevation dan foydalaning.

Qaysi biri tezroq: FrameLayout yoki ConstraintLayout?

FrameLayout tezroq juda oddiy holatlar uchun — bitta bola elementi, murakkab joylashtirishsiz. FrameLayout onMeasure-ni minimal vaqtda bajaradi, konstraintlarni hisoblamaydi. Biroq farq faqat yuzlab takrorlashlarda (o'n minglab elementlarda RecyclerView) seziladi. Oddiy ekran (1–3 FrameLayout) uchun farq mikrosekundlarda va UX-ga ta'sir qilmaydi. ConstraintLayout 95% vazifalar uchun universal tanlovdir.

Xulosa

  • FrameLayout — minimal qo'shimcha yuk bilan elementlarni ustma-ust qo'yish va placeholder konteynerlar uchun Android-ning eng oddiy ViewGroup-i.
  • Qatlamlarning ustma-ust qo'yilishi — har bir yangi child oldingisining ustida chiziladi; XML-da eng oxirgi e'lon qilingani eng yuqorida.
  • Foreground — overlay effektlari, maskalash va ripple animatsiyasi uchun barcha bolalar ustidagi drawable.
  • measureAllChildren — o'chirish (false) GONE elementlarini o'lcham hisobidan chiqaradi, renderlashni 20–60% tezlashtiradi.
  • layout_gravity — yagona joylashtirish mexanizmi: top, bottom, left, right, center va ularning kombinatsiyalari.
  • Fragment konteyneri — eng keng tarqalgan foydalanish holati: FragmentTransaction.replace() uchun FrameLayout (yoki FragmentContainerView).
  • Ishlash — 1 child uchun eng tez konteyner; murakkab layoutlar uchun ConstraintLayout-dan past.

Biz kalit topshirig'i bilan mobil ilovani ishlab chiqamiz

IT Sectr 2017-yildan beri startaplar va korxonalar uchun iOS va Android ilovalarini yaratadi. Biz sizga maslahat beramiz va eng yaxshi yechimni taklif qilamiz.

Loyihani muhokama qilish

Shuningdek o'qing