FrameLayout — Android SDK-da ən sadə ViewGroup, adətən bir uşaq elementinin yerləşdirilməsi və ya bir neçə elementin bir-birinin üzərinə qoyulması üçün nəzərdə tutulub. FrameLayout placeholder konteynerləri, fraqmentlər, yükləmə göstəriciləri və ön plan elementləri üçün əlverişlidir. O, uşaqların yerləşməsini idarə etmir — hər növbəti element əvvəlkinin üzərində çəkilir və onların mövqeyi layout_gravity (left, top, right, bottom, center) ilə müəyyən edilir. Əsas ssenarilər FrameLayout API Reference-da təsvir edilmişdir.
Əsas məqamlar
FrameLayout Android SDK-da ən sadə ViewGroup-dur, ekran sahəsini bloklamaq və bir uşaq görünüşünü (və ya bir neçəsinin üst-üstə qoyulmasını) göstərmək üçün nəzərdə tutulub. LinearLayout (ardıcıl yerləşdirmə) və RelativeLayout-dən (nisbi yerləşdirmə) fərqli olaraq, FrameLayout uşaqların mövqeyini dəyişmir — hər yeni child standart olaraq sol yuxarı küncə (0,0) yerləşdirilir və əvvəlkinin üzərində çəkilir.
FrameLayout API Level 1-də ortaya çıxıb və Android-in ən yüngül konteyneri olaraq qalır: o, onMeasure-ni mürəkkəb məntiqlə əvəz etmir və minimal sayda layout əməliyyatı yerinə yetirir. Android Performance Blog-a görə, FrameLayout onLayout-u bir keçiddə yerinə yetirir və birbaşa View yerləşdirmə ilə müqayisədə praktiki olaraq əlavə yük yaratmır. Bu onu sürətin vacib olduğu konteynerlər üçün ideal edir: RecyclerView item-layoutları (yerləşdirmə üçün ConstraintLayout ilə birlikdə), Fragment konteynerləri, overlay təbəqələri.
FrameLayout-un standart ölçüsü ən böyük uşaq elementi ilə müəyyən edilir (əgər match_parent təyin edilməyibsə). Heç bir child göstərilməyibsə, FrameLayout (0,0)-a qədər yığılır. android:measureAllChildren atributu (aşağıdakı bölmə) bu davranışı dəyişir.
FrameLayout ViewGroup-dan miras alır və bir çox ixtisaslaşmış konteynerlərin birbaşa valideynidir: FragmentContainerView (fraqmentlər), CardView (kölgəli kartlar), ScrollView (bir child ilə), NestedScrollView. Fragment naviqasiyası ilə Activity yaradarkən Android Studio-nun standart şablonu fraqmentlər üçün əsas konteyner kimi FrameLayout-dan (və ya FragmentContainerView) istifadə edir.
android:foreground — bütün uşaq elementlərin üzərində çəkilən drawable-ı təyin edən FrameLayout atributu. Background-dan (uşaqların altında) fərqli olaraq, foreground məzmunun üstündə göstərilir və şəffaf ola bilər. İstifadə olunur: sıxma effektləri (ripple ?attr/selectableItemBackground ilə), şəkillərin maskalanması, status göstəricilərinin (şəklin üzərində seçim işarəsi) göstərilməsi üçün.
Foreground standart drawable resurslarını dəstəkləyir: ColorDrawable, ShapeDrawable, RippleDrawable, LayerDrawable. API 23+-dan etibarən foreground-u yerləşdirmək üçün android:foregroundGravity (fill, center, top, bottom) mövcuddur. "Doldur" (fill) rejimində foreground bütün FrameLayout-a yayılır; center rejimində — mərkəzdə çəkilir.
android:measureAllChildren — FrameLayout-un ölçüsünü hesablayarkən bütün uşaq elementlərin ölçülməsinin lazım olub-olmadığını təyin edən boolean atribut (standart true). true (standart) olduqda, FrameLayout GONE (ölçüsü 0) daxil olmaqla bütün uşaqların ölçülərini nəzərə alır. false olduqda, FrameLayout yalnız görünən (VISIBLE) və görünməyən (INVISIBLE) uşaqları ölçür — GONE elementləri hesablamadan çıxarılır. Google I/O 2019-a görə, çox sayda GONE elementi olan konteynerlər (məsələn, görünməsi dəyişən siyahılar) üçün measureAllChildren-ı söndürmək ilkin renderi 20–60% sürətləndirir.
android:layout_gravity — FrameLayout (və digər ViewGroup) uşaq elementinin konteyner daxilində mövqeyini təyin edən atributudur. FrameLayout-da layout_gravity uşaq elementinin yerləşməsini idarə etməyin yeganə yoludur, çünki FrameLayout öz yerləşdirmə qaydalarını (RelativeLayout kimi) və ya istiqaməti (LinearLayout kimi) təmin etmir.
Mümkün dəyərlər: top, bottom, left, right, center, center_horizontal, center_vertical, fill, fill_horizontal, fill_vertical, clip_horizontal, clip_vertical. | ilə birləşdirilir: android:layout_gravity="bottom|center_horizontal" — element aşağı kənara sıxılır və üfüqi olaraq mərkəzləşdirilir. Ölçüsü FrameLayout-dan kiçik olan elementlər üçün layout_gravity onların boş yerdəki mövqeyini təyin edir.
layout_gravity təyin edilməyibsə, standart olaraq element sol yuxarı küncə (top|left) yerləşdirilir. Bir neçə uşağı olan FrameLayout-da hər birinin öz layout_gravity-si ola bilər — bir element sol yuxarı küncdə, digəri sağ aşağı küncdə, üçüncüsü mərkəzdə ola bilər. Bu, sadə üst-üstə qoymalar yaratmağa imkan verir (məsələn, şəklin üzərində bağlama xaçı).
android:gravity (valideyn atributu) FrameLayout daxilində məzmunu düzləşdirir — məsələn, TextView daxilində mətn. android:layout_gravity (uşaq atributu) elementin özünü FrameLayout daxilində düzləşdirir. FrameLayout kontekstində gravity uşaqların standart olaraq necə yerləşdiyini müəyyən edir (bütün uşaqlar üçün layout_gravity analoqu), lakin hər bir elementin layout_gravity-si valideyn dəyərini ləğv edir.
Şəkil və sağ aşağı küncdə mətn etiketi. FrameLayout bütün ekranı əhatə edən ImageView və üstünə yerləşdirmək üçün layout_gravity="bottom|end" olan TextView ehtiva edir.
<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 bütün FrameLayout-u (200dp hündürlük) tutur. layout_gravity="bottom|end" olan TextView şəklin üzərində sağ aşağı küncdə yerləşdirilir. elevation=2dp etiketin altına kölgə əlavə edərək onu şəkildən vizual olaraq ayırır. Bu LinearLayout-da iç-içə konteyner və ya xüsusi kod tələb edəcək minimal nümunədir.
Məzmunu və yükləmə zamanı görünən mərkəzdə yerləşən proqress barı olan ekran. FrameLayout iki elementdən ibarətdir: məzmun və visibility="gone" olan ProgressBar (kodda dəyişdirilir).
<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="Yüklənmiş məzmun"
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 olaraq gizlidir (gone). Yükləmə başlayanda kodda findViewById(R.id.loading_spinner).visibility = View.VISIBLE çağırılır — spinner məzmunun üzərində mərkəzdə görünür. Yükləmə bitdikdən sonra — .visibility = View.GONE. FrameLayout məzmunun mövqeyini dəyişmədən üst-üstə qoymağı təmin edir — ProgressBar üstə çəkildiyi üçün spinner görünəndə mətn yerdəyişməz.
FrameLayout FragmentTransaction üçün standart konteyner kimi. Aktivlik naviqasiyadan asılı olaraq bu konteyner daxilində fraqmentləri dəyişir.
<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 fraqment konteyneri kimi — Fragment Navigation-u dəstəkləməyin ən yüngül yoludur. FragmentContainerView (FrameLayout-dan miras alan) Navigation Component 2.4+-da tövsiyə olunur, lakin sadə FrameLayout əl ilə FragmentTransaction üçün etibarlı olaraq qalır. Əsas üstünlük — FragmentTransaction.replace() Activity-yə təsir etmədən məzmunu tamamilə əvəz edir.
FrameLayout dörd ssenari üçün optimaldır: fraqment konteyneri (FragmentContainerView və ya FrameLayout), yükləmə overlay-i (məzmunun üzərində ProgressBar), kart etiketləri (şəklin üzərində işarə), ViewStub üçün placeholder konteyner (tənbəl yükləmə).
Uyğun deyil: bir neçə elementin mürəkkəb yerləşdirilməsi (ConstraintLayout istifadə edin), ardıcıl siyahılar (LinearLayout və ya RecyclerView), elementlərin sırasının dəyişdiyi dinamik layoutlar.
FrameLayout ekranın kök elementi kimi — ekranda 2–3-dən çox element varsa, pis təcrübədir. Kök konteyner üçün ConstraintLayout istifadə edin — performans itkisi olmadan yerləşdirmə üzərində daha çox nəzarət verir. FrameLayout-ı yalnız üst-üstə qoyma və ya placeholder lazım olan uşaq blokları üçün istifadə edin.
Tez-tez verilən suallar
FrameLayout — yalnız layout_gravity ilə yerləşdirmə sistemi olmayan minimalist konteyner, elementlərin üst-üstə qoyulması üçün nəzərdə tutulub. ConstraintLayout — konstraintlər, zəncirlər, baryerlər, faiz ölçüləri və MotionLayout dəstəyi ilə tam hüquqlu layout sistemi. FrameLayout sadə hallar (1 child və ya overlay) üçün daha sürətlidir; ConstraintLayout mürəkkəb maketlər üçün məcburidir. Seçim: FrameLayout yükləmə overlay-i və fraqment konteyneri üçün; ConstraintLayout qalan hər şey üçün.
Lazım olan oxda FrameLayout ölçüsünü wrap_content edin (android:layout_width="wrap_content" və/və ya android:layout_height="wrap_content"). Bu halda FrameLayout ən böyük uşaq elementinin ölçüsünə uyğunlaşacaq. Bütün uşaqlar FrameLayout-dan kiçikdirsə, artıq boşluq qalacaq. Dəqiq nəzarət üçün sabit padding ilə match_parent istifadə edin.
Bu FrameLayout-un normal davranışıdır — o, uşaqları məkanda paylamır, ardıcıl olaraq bir-birinin üzərində çəkir. Elementlərin üst-üstə düşməməsini istəyirsinizsə, başqa konteynerdən (LinearLayout, ConstraintLayout) istifadə edin. Çəkmə sırasına nəzarətlə qismən üst-üstə qoyma üçün yerdəyişmə üçün layout_gravity və Z-order üçün elevation istifadə edin.
FrameLayout daha sürətlidir maksimum sadə hallar üçün — bir uşaq elementi, mürəkkəb yerləşdirmə olmadan. FrameLayout onMeasure-ni minimal vaxtda yerinə yetirir, konstraintləri hesablamır. Lakin fərq yalnız yüzlərlə təkrarlamada (on minlərlə elementdə RecyclerView) nəzərə çarpır. Adi ekran (1–3 FrameLayout) üçün fərq mikrosaniyələrdədir və UX-ə təsir etmir. ConstraintLayout 95% tapşırıq üçün universal seçimdir.
Nəticə
Açar təslim mobil tətbiq hazırlayacağıq
IT Sectr 2017-ci ildən startaplar və bizneslər üçün iOS və Android tətbiqləri yaradır. Sizə məsləhət verəcəyik və ən yaxşı həlli təklif edəcəyik.
Həm də oxuyun