FrameLayout temel kavramlarını öğrenin — Android SDK'daki en basit ViewGroup, genellikle tek bir alt öğeyi barındırmak veya birden çok öğeyi üst üste yerleştirmek için tasarlanmıştır. FrameLayout, yer tutucu kaplar, fragmentler, yükleme göstergeleri ve ön plan öğeleri için uygundur. Alt öğelerin konumlandırmasını yönetmez — sonraki her öğe bir öncekinin üzerine çizilir ve konumları layout_gravity (left, top, right, bottom, center) tarafından belirlenir. Temel senaryolar FrameLayout API Referansı'nda açıklanmıştır.
Önemli Çıkarımlar
FrameLayout, Android SDK'daki en basit ViewGroup'tur ve bir ekran alanını bloke etmek ve tek bir alt görünüm (veya birden çok bindirme) görüntülemek için tasarlanmıştır. LinearLayout (sıralı yerleşim) ve RelativeLayout'ten (göreceli konumlandırma) farklı olarak FrameLayout, alt öğelerin konumlarını değiştirmez — her yeni alt öğe varsayılan olarak sol üst köşeye (0,0) yerleştirilir ve bir öncekinin üzerine çizilir.
FrameLayout, API Level 1'de tanıtılmıştır ve hâlâ en hafif Android kabıdır: karmaşık mantıkla onMeasure'u geçersiz kılmaz ve minimum sayıda layout işlemi gerçekleştirir. Android Performance Blog'a göre FrameLayout, onLayout'u tek geçişte yürütür ve bir View'i doğrudan yerleştirmeye kıyasla neredeyse hiç ek yük eklemez. Bu, hızın önemli olduğu kaplar için onu ideal bir seçim haline getirir: RecyclerView öğe düzenleri (konumlandırma için ConstraintLayout ile birlikte), Fragment kapları, bindirme katmanları.
FrameLayout'un boyutu varsayılan olarak en büyük alt öğe tarafından belirlenir (match_parent ayarlanmamışsa). Hiçbir alt öğe belirtilmezse FrameLayout (0,0)'a küçülür. android:measureAllChildren özelliği (aşağıdaki bölüm) bu davranışı değiştirir.
FrameLayout, ViewGroup'tan miras alır ve birçok özelleşmiş kabın doğrudan ebeveynidir: FragmentContainerView (fragmentler), CardView (gölgeli kartlar), ScrollView (tek alt öğe), NestedScrollView. Fragment navigasyonuyla bir Activity oluştururken, standart Android Studio şablonu fragmentler için kök kap olarak FrameLayout (veya FragmentContainerView) kullanır.
android:foreground — tüm alt öğelerin üzerine çizilen bir drawable belirten FrameLayout özelliğidir. Background'un (alt öğelerin altında) aksine foreground, içeriğin üzerinde görüntülenir ve şeffaf olabilir. Şunlar için kullanılır: dokunmada bindirme efektleri (?attr/selectableItemBackground ile ripple), görüntü maskeleme, durum göstergelerini görüntüleme (görüntü üzerinde seçim onay işareti).
Foreground, standart drawable kaynaklarını destekler: ColorDrawable, ShapeDrawable, RippleDrawable, LayerDrawable. API 23+'ten itibaren ön plan konumlandırması için android:foregroundGravity kullanılabilir (fill, center, top, bottom). Doldurma modunda (fill) foreground tüm FrameLayout'a yayılır; orta modda merkeze çizilir.
android:measureAllChildren — FrameLayout boyutunu hesaplarken tüm alt öğelerin ölçülüp ölçülmeyeceğini belirleyen bir boole özelliğidir (varsayılan true). true (varsayılan) ise FrameLayout, GONE (boyut 0 ile) dahil tüm alt öğelerin boyutlarını dikkate alır. false ise FrameLayout yalnızca VISIBLE ve INVISIBLE alt öğeleri ölçer — GONE öğeleri hesaplamadan çıkarılır. Google I/O 2019'a göre, çok sayıda GONE öğesi (örneğin, görünürlüğü değişen listeler) içeren kaplar için measureAllChildren'ı devre dışı bırakmak ilk çizimi %20–60 hızlandırır.
android:layout_gravity — FrameLayout (ve diğer ViewGroup'lar) alt öğesinin, kap içindeki konumunu tanımlayan bir özelliğidir. FrameLayout'da layout_gravity, bir alt öğenin konumunu kontrol etmenin tek yoludur çünkü FrameLayout kendi konumlandırma kurallarını (RelativeLayout gibi) veya yönünü (LinearLayout gibi) sağlamaz.
Olası değerler: top, bottom, left, right, center, center_horizontal, center_vertical, fill, fill_horizontal, fill_vertical, clip_horizontal, clip_vertical. | ile birleştirilir: android:layout_gravity="bottom|center_horizontal" — öğe alt kenara sabitlenir ve yatay olarak ortalanır. FrameLayout'tan küçük öğeler için layout_gravity, boş alandaki konumlarını belirler.
layout_gravity ayarlanmazsa öğe varsayılan olarak sol üst köşeye (top|left) yerleştirilir. Birden çok alt öğe içeren bir FrameLayout için her biri kendi layout_gravity'sine sahip olabilir — bir öğe sol üst köşede, diğeri sağ alt köşede, üçüncüsü ortada olabilir. Bu, basit bindirmeler oluşturmayı sağlar (örneğin, bir görüntü üzerinde kapatma simgesi).
android:gravity (ebeveyn özelliği) FrameLayout içindeki içeriği hizalar — örneğin, bir TextView içindeki metin. android:layout_gravity (alt özellik) öğenin kendisini FrameLayout içinde hizalar. FrameLayout bağlamında gravity, alt öğelerin varsayılan olarak nasıl konumlandırılacağını tanımlar (tüm alt öğeler için aynı anda layout_gravity'ye benzer), ancak her bir öğenin layout_gravity'si ebeveyn değerini geçersiz kılar.
Sağ alt köşede metin etiketi bulunan bir görüntü. FrameLayout, ekranı dolduran bir ImageView ve görüntü üzerinde konumlandırma için layout_gravity="bottom|end" olan bir TextView içerir.
<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 tüm FrameLayout'u (200dp yükseklik) doldurur. layout_gravity="bottom|end" olan TextView, görüntünün üzerinde sağ alt köşeye yerleştirilir. elevation=2dp, etiketin altına gölge ekleyerek onu görüntüden görsel olarak ayırır. Bu minimum örnek, LinearLayout'da iç içe bir kap veya özel kod gerektirirdi.
Yükleme sırasında görünen ortalanmış ilerleme çubuğuna sahip bir ekran. FrameLayout iki öğe içerir: içerik ve visibility="gone" olan bir ProgressBar (kodda değiştirilir).
<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üklenen içerik"
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 varsayılan olarak gizlidir (gone). Yükleme başladığında findViewById(R.id.loading_spinner).visibility = View.VISIBLE çağrılır — döndürücü içeriğin üzerinde ortalanmış olarak görünür. Yüklemeden sonra — .visibility = View.GONE. FrameLayout, içerik konumunu kaydırmadan bindirme sağlar — ProgressBar üstte çizildiği için döndürücü göründüğünde metin hareket etmez.
FragmentTransaction için standart kap olarak FrameLayout. Aktivite, navigasyona bağlı olarak bu kabın içindeki fragmentleri değiştirir.
<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()
}
Fragment kabı olarak FrameLayout, Fragment Navigation'ı desteklemenin en hafif yoludur. Navigation Component 2.4+ ile FragmentContainerView (FrameLayout'un bir alt sınıfı) önerilir, ancak basit bir FrameLayout manuel FragmentTransaction'lar için geçerliliğini korur. Temel avantajı, FragmentTransaction.replace()'in Activity'yi etkilemeden içeriği tamamen değiştirmesidir.
FrameLayout dört senaryo için idealdir: fragment kabı (FragmentContainerView veya FrameLayout), yükleme bindirmesi (içerik üzerinde ProgressBar), kart etiketleri (görüntü üzerinde etiket), ViewStub için yer tutucu kap (tembel yükleme).
Şunlar için uygun değildir: birden çok öğenin karmaşık konumlandırması (ConstraintLayout kullanın), sıralı listeler (LinearLayout veya RecyclerView), öğe sırası değişen dinamik düzenler.
Ekranın kök öğesi olarak FrameLayout — ekran 2–3'ten fazla öğe içeriyorsa kötü uygulamadır. Kök kap için ConstraintLayout kullanın — performans kaybı olmadan konumlandırma üzerinde daha fazla kontrol sağlar. FrameLayout'u yalnızca bindirme veya yer tutucu gereken alt bloklar için kullanın.
Sıkça Sorulan Sorular
FrameLayout — konumlandırma sistemi olmayan (yalnızca layout_gravity) minimalist bir kap, öğeleri bindirmek için tasarlanmıştır. ConstraintLayout — kısıtlamalar, zincirler, bariyerler, yüzde boyutları ve MotionLayout desteği ile tam teşekküllü bir düzen sistemidir. FrameLayout basit durumlar (1 alt öğe veya bindirme) için daha hızlıdır; karmaşık düzenler için ConstraintLayout gereklidir. Seçim: yükleme bindirmesi ve fragment kabı için FrameLayout; diğer her şey için ConstraintLayout.
İstenen eksende FrameLayout boyutunu wrap_content olarak ayarlayın (android:layout_width="wrap_content" ve/veya android:layout_height="wrap_content"). FrameLayout daha sonra en büyük alt öğenin boyutuna uyum sağlayacaktır. Tüm alt öğeler FrameLayout'tan küçükse, fazla alan boş kalır. Hassas kontrol için sabit padding ile match_parent kullanın.
Bu FrameLayout'un amaçlanan davranışıdır — alt öğeleri alana dağıtmaz, sırayla üst üste çizer. Öğelerin üst üste binmesini istemiyorsanız başka bir kap (LinearLayout, ConstraintLayout) kullanın. Çizim sırasını kontrol ederek kısmi bindirme için ofset için layout_gravity ve Z-sırası için elevation kullanın.
FrameLayout daha hızlıdır en basit durumlar için — bir alt öğe, karmaşık konumlandırma yok. FrameLayout, kısıtlamaları hesaplamadan minimum sürede onMeasure'u gerçekleştirir. Ancak fark yalnızca yüzlerce tekrarda (on binlerce öğeye sahip RecyclerView) fark edilir. Tipik bir ekran (1–3 FrameLayout) için fark mikrosaniyelerdir ve UX'i etkilemez. ConstraintLayout, görevlerin %95'i için evrensel seçimdir.
Özet
Anahtar teslim bir mobil uygulama geliştireceğiz
IT Sectr, 2017'den beri girişimler ve işletmeler için iOS ve Android uygulamaları oluşturmaktadır. Size danışmanlık yapacak ve en iyi çözümü önereceğiz.
Ayrıca okuyun