LinearLayout temellerini açıklıyoruz — Android SDK'da alt öğeleri dikey (LinearLayout.VERTICAL) veya yatay (LinearLayout.HORIZONTAL) olarak tek bir satırda hizalamak için temel bir ViewGroup. LinearLayout, düzen karmaşıklığı 5–10 öğeyi aşmadığında bir dizi düğme, ayarlar listesi veya giriş formu oluşturmanın en basit ve en hızlı yolu olmaya devam ediyor. layout_weight ve orientation öznitelikleri alan dağıtımını ve yönü yönetir. Ayrıntılı spesifikasyon — LinearLayout API Reference adresinde.
Önemli Noktalar
LinearLayout — Android SDK'daki (API Level 1) ilk ViewGroup'lardan biri, alt öğeleri sıralı olarak tek bir satır veya sütuna yerleştirmek için tasarlanmıştır. Her yeni öğe bir öncekinin ardından konumlandırılır ve yön android:orientation özniteliğiyle belirlenir. LinearLayout, en basit ve öngörülebilir Android kapsayıcısıdır ve onu doğrusal arayüzler için ideal seçim haline getirir: düğme sıraları, simge ve metin içeren ayarlar listeleri, yatay menüler.
Tarihsel olarak LinearLayout, yeni başlayan bir Android geliştiricisinin tanıştığı ilk ViewGroup'dur. Avantajı şeffaflıktır: alt öğeler, gizli konumlandırma kuralları olmadan bildirim sırasına göre kesin bir şekilde yerleştirilir. Bir öğenin herhangi bir komşuya bağlanabildiği RelativeLayout veya kısıtlama sistemiyle ConstraintLayout'un aksine, LinearLayout "önce sol/üst, ondan sonra ikinci, ikinciden sonra üçüncü" prensibiyle çalışır. Google I/O 2017'ye göre, Google Play'deki ilk 1000 uygulamadaki ekranların %78'i LinearLayout'u birincil veya yardımcı kapsayıcı olarak kullanır.
LinearLayout'un ana metriği LinearLayout.MeasureSpec — boyut yönetim sistemidir. VERTICAL yönlendirmede, her öğenin genişliği üst öğenin genişliğine (match_parent veya sabit) eşittir ve yükseklik içerik veya öznitelik tarafından belirlenir. HORIZONTAL için bunun tersi geçerlidir: yükseklik üst öğeye eşit, genişlik içeriğe göre. Bir HORIZONTAL satırında toplam öğe genişliği üst öğenin genişliğini aşarsa, öğeler ekranın dışına taşabilir (weight kullanılmazsa).
LinearLayout, ViewGroup'dan onMeasure ve onLayout'u geçersiz kılar. VERTICAL yönlendirmede, onLayout öğeleri Y ekseni boyunca yerleştirir: ilk alt öğe — y=0, ikinci — y=prev.bottom + divider.hidden, vb. HORIZONTAL'da — X ekseni boyunca. Ayırıcı, android:divider ve android:showDividers (beginning, middle, end) aracılığıyla ayarlanır. Ayırıcı bir renk, drawable veya özel Shape kaynağı olabilir.
Yönlendirme — alt öğelerin yerleştirme yönünü belirleyen önemli bir LinearLayout özniteliğidir. android:orientation="vertical" öğeleri yukarıdan aşağıya düzenler; android:orientation="horizontal" — soldan sağa (veya RTL yerelleştirmesiyle sağdan sola). Yönlendirme ayarlanmazsa, varsayılan olarak HORIZONTAL kullanılır (eski sürümlerde) — ancak öngörülebilir davranış için açık belirtme gereklidir.
android:gravity — içeriği LinearLayout içinde hizalar. Şu kombinasyonları kabul eder: top, bottom, left, right, center, center_horizontal, center_vertical, fill, clip_vertical, clip_horizontal. VERTICAL düzen için gravity="center" değeri tüm öğeleri yatay olarak ortalar. android:layout_gravity — alt öğeyi üst LinearLayout içinde hizalayan bir alt öğe özniteliğidir. Örnek: VERTICAL düzende layout_gravity="right" olan bir düğme, düğmeyi sağ kenara iter.
Fark: gravity — üst öğenin özelliği (alt öğelerin içinde nasıl düzenlendiği), layout_gravity — alt öğenin özelliği (üst öğe içinde nasıl davrandığı). Bu öznitelikleri karıştırmak, yeni başlayanlar arasında en yaygın hatalardan biridir.
Metin öğeleri (TextView, Button, EditText) içeren HORIZONTAL düzenler için android:baselineAligned="true" kullanışlıdır — tüm metinleri dolgu, boyut veya yükseklikten bağımsız olarak yazı tipi taban çizgisine göre hizalar. Bu, bir simge, başlık ve açıklama içeren bir satırı görsel olarak düzenli hale getirir: metin yukarı aşağı zıplamaz.
layout_weight — LinearLayout'un bir alt öğe özniteliğidir ve boş alanın ne kadarını kaplayacağını belirler. Yalnızca yönlendirme yönünde çalışır (HORIZONTAL için genişlik, VERTICAL için yükseklik). Hesaplama formülü: boyut = kendi boyutu + (boş alan × (öğe ağırlığı / tüm ağırlıkların toplamı)). Boş alan = üst öğe boyutu — tüm alt öğelerin kendi boyutlarının toplamı.
layout_weight, uyarlanabilir arayüzler için sabit boyutlardan daha verimlidir. Örneğin, sol panel ekranın %30'unu ve sağ panel %70'ini kaplamalıysa, weight=3 ve weight=7 olarak ayarlayın. Doğru çalışma için, yöndeki boyut genellikle 0dp olarak ayarlanır (HORIZONTAL için android:layout_width="0dp"), ardından öğenin kendi boyutu sıfır kabul edilir ve tüm boyut yalnızca weight tarafından belirlenir. Bu, Google'ın standart önerisidir (Android Developers Guide, 2024).
Önemli: ağırlıklar, weight ayarlanmamış olanlar da dahil olmak üzere (ağırlıkları 0 kabul edilir) LinearLayout'daki tüm öğeler için toplanır. Bir öğenin weight=1 ve diğerinin weight=2'si varsa, birincisi boş alanın 1/3'ünü, ikincisi — 2/3'ünü kaplar. weightSum (bir üst öğe özniteliği) maksimum ağırlık toplamını ayarlamaya izin verir — alt öğe ağırlıklarının toplamı weightSum'dan küçükse, fark boş alan olarak kalır.
Giriş formu üç öğeden oluşur: e-posta alanı (ekran yüksekliğinin 2/4'ünü kaplar), şifre alanı (1/4) ve düğme (1/4). Weight'e sahip her üç öğe de yalnızca VERTICAL yönlendirmede yüksekliğe göre çalışır.
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="16dp">
<EditText
android:id="@+id/email"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="2"
android:hint="Email" />
<EditText
android:id="@+id/password"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:hint="Şifre"
android:inputType="textPassword" />
<Button
android:id="@+id/login_button"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:text="Giriş Yap" />
</LinearLayout>
Her öğenin yüksekliği = (parent_height — padding) × (weight / sumWeights). email yüksekliğin 2/4'ünü, şifre ve düğme — her biri 1/4'ünü alır. Tümü height=0dp, bu nedenle kendi boyutu dikkate alınmaz — yalnızca weight çalışır.
Üç düğmeli bir panel: geri simgesi (wrap_content), başlık (kalanı doldur) ve menü simgesi (wrap_content). Başlık için weight=1, düğmeler weightsiz.
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="56dp"
android:gravity="center_vertical">
<ImageButton
android:id="@+id/btn_back"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_arrow_back" />
<TextView
android:id="@+id/toolbar_title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Başlık"
android:textSize="18sp" />
<ImageButton
android:id="@+id/btn_menu"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_more_vert" />
</LinearLayout>
Geri ve menü düğmeleri, simge için gereken kadar alanı tam olarak kaplar. width=0dp ve weight=1 olan başlık (TextView), aralarındaki kalan tüm alana yayılır. gravity="center_vertical" tüm öğeleri dikey olarak ortalar.
Bir ürün kartı: yatay satır (görsel + dikey metin bloğu). Dış LinearLayout HORIZONTAL, iç — başlık, açıklama ve fiyat için VERTICAL.
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="8dp">
<ImageView
android:layout_width="80dp"
android:layout_height="80dp"
android:src="@drawable/product_image"
android:scaleType="centerCrop" />
<LinearLayout
android:orientation="vertical"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginStart="12dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Ürün adı"
android:textStyle="bold"
android:textSize="16sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="İki satırda kısa ürün açıklaması"
android:textSize="14sp"
android:textColor="@color/gray" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="1.299 RUB"
android:textSize="18sp"
android:textColor="@color/accent" />
</LinearLayout>
</LinearLayout>
Solda görsel (80×80dp), sağda — üç metin satırından oluşan dikey bir blok. İç LinearLayout'un weight=1 değeri vardır, bu nedenle görselden sonra kalan tüm alanı kaplar. Bu, binlerce uygulamada bulunan klasik bir liste kartı desenidir.
LinearLayout'un ana dezavantajı — karmaşık düzenler için iç içe kapsayıcılara duyulan ihtiyaçtır. Öğeleri 2×2'lik bir ızgarada düzenlemeniz veya her iki kenarda hizalamalı bir satır oluşturmanız gerekiyorsa, en az 2–3 iç içe geçirme seviyesi gerekir. Her LinearLayout seviyesi 2 onMeasure geçişi ekler ve bu da zayıf cihazlarda işleme sırasında gözle görülür gecikmelere yol açar.
Android Performance Blog'a (Google, 2017) göre, her ek iç içe geçirme seviyesi düzen süresini 30–50 μs artırır. 3 iç içe geçirme seviyesine sahip 20 öğelik bir liste için gecikme, öğe başına 3 ms'ye ulaşabilir — bu, kaydırma sırasında gözle görülür bir takılmadır (jank). ConstraintLayout, düz bir hiyerarşi aracılığıyla bu sorunu çözer ve 3–4 iç içe LinearLayout'u tek bir kısıtlama kapsayıcısıyla değiştirir.
Öneri: basit doğrusal düzenler için (10 öğeye kadar, bir iç içe geçirme seviyesi) LinearLayout kullanın. Liste kartları, farklı hizalamalı formlar ve tablo yapılı ekranlar için ConstraintLayout'u seçin. RecyclerView'daki yinelenen öğeler için öğe düzen dosyasında ConstraintLayout kullanın — bu, kaydırma performansı için kritiktir.
Sıkça Sorulan Sorular
En yaygın neden — yöndeki boyut 0dp olarak ayarlanmamıştır. HORIZONTAL düzen için android:layout_width="0dp", VERTICAL için — android:layout_height="0dp" gerekir. Öğede wrap_content veya match_parent varsa, weight çalışmayabilir veya beklenmeyen sonuçlar verebilir. İkinci neden — üst öğedeki weightSum, alt öğelerin ağırlıklarının toplamından azdır. Üçüncü — zıt yöndeki bir alt öğede match_parent kullanmak.
layout_weight her alt öğede ayarlanır ve boş alandaki payını belirler. weightSum — üst LinearLayout'un maksimum ağırlık toplamını ayarlayan bir özniteliğidir. Varsayılan olarak weightSum = tüm alt öğelerin layout_weight toplamıdır. weightSum = 3 olarak ayarlarsanız ve alt öğelerin weight=1'i varsa, her biri 1/3 kaplar. Yalnızca weight=1 olan iki alt öğe varsa, kalan 1/3 boş olur. weightSum, öğe eklerken/kaldırırken yeniden hesaplama yapmadan oranları sabitlemek için kullanışlıdır.
Varsayılan olarak boşluk yoktur — öğeler bitişik olarak yerleştirilir. Boşluklar görünürse, şunları kontrol edin: üst öğede android:divider ve android:showDividers, alt öğelerde android:layout_margin. Ek olarak, android:weightSum etkileyebilir — öğeler weight kullanıyorsa, hatalı hesaplama nedeniyle aralarında boş alan kalabilir. Sıfır boşluk için tüm alt öğe kenar boşluklarını 0dp yapın ve ayırıcıyı kaldırın.
Basit tek yönlü düzenler için (bir satır/sütunda 1–5 öğe) LinearLayout biraz daha hızlıdır — kısıtlama hesaplamasına kaynak harcamaz. Karmaşık düzenler için (5'ten fazla öğe, ızgaralar, farklı hizalama türleri) ConstraintLayout daha hızlıdır çünkü iç içe LinearLayout'lar yerine düz bir hiyerarşi kullanır. Google testlerine (Android Performance Blog) göre ConstraintLayout, 3+ seviye LinearLayout iç içe geçirme gerektiren düzenlerde kazanır.
Ö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