LinearLayout: elemente de bază, orientare și distribuirea greutății în Android

Autor: IT Sectr Publicat: 2026-02-24 Timp de citire: 9 min

Explicăm elementele de bază ale LinearLayout — ViewGroup de bază în Android SDK pentru alinierea elementelor copil într-o singură linie: vertical (LinearLayout.VERTICAL) sau orizontal (LinearLayout.HORIZONTAL). LinearLayout rămâne cel mai simplu și rapid mod de a construi un rând de butoane, o listă de setări sau un formular de intrare, când complexitatea layout-ului nu depășește 5–10 elemente. Atributele layout_weight și orientation controlează distribuția spațiului și direcția. Specificația detaliată — în LinearLayout API Reference.

Principalele puncte

  • Orientarea — LinearLayout plasează elementele secvențial vertical (VERTICAL) sau orizontal (HORIZONTAL), setată prin android:orientation.
  • layout_weight — distribuirea spațiului liber proporțional cu greutatea elementelor; suma greutăților determină cota fiecăruia.
  • gravity vs layout_gravity — android:gravity aliniază conținutul în interiorul LinearLayout; android:layout_gravity aliniază elementul însuși în interiorul părintelui.
  • Încuibarea — principalul dezavantaj: pentru o rețea complexă este necesară încuibarea mai multor LinearLayout, ceea ce reduce performanța.
  • Baseline alignment — alinierea elementelor text după linia de bază a fontului, independent de padding și înălțimea elementului.

Ce este LinearLayout?

LinearLayout — una dintre primele ViewGroup din Android SDK (API Level 1), destinată plasării secvențiale a elementelor copil într-un singur rând sau coloană. Fiecare element nou este plasat după cel precedent, iar direcția este stabilită prin atributul android:orientation. LinearLayout este cel mai simplu și mai previzibil container Android, ceea ce îl face alegerea ideală pentru interfețe liniare: rânduri de butoane, liste de setări cu pictogramă și text, meniuri orizontale.

Istoric, LinearLayout este primul ViewGroup cu care se familiarizează un dezvoltator Android începător. Avantajul său este transparența: elementele copil sunt plasate strict în ordinea declarării, fără reguli ascunse de poziționare. Spre deosebire de RelativeLayout, unde un element poate fi legat de orice vecin, sau ConstraintLayout cu sistemul său de constrângeri, LinearLayout funcționează pe principiul „primul la stânga/sus, al doilea după el, al treilea după al doilea”. Conform Google I/O 2017, 78% din ecranele din top 1000 de aplicații Google Play folosesc LinearLayout ca container principal sau auxiliar.

Metrica principală a LinearLayout — LinearLayout.MeasureSpec — sistemul de gestionare a dimensiunii. La orientarea VERTICAL lățimea fiecărui element este egală cu lățimea părintelui (match_parent sau fixă), iar înălțimea este determinată de conținut sau de atribut. Pentru HORIZONTAL invers: înălțimea este egală cu cea a părintelui, lățimea — după conținut. Dacă într-un rând HORIZONTAL lățimea totală a elementelor depășește lățimea părintelui, elementele pot ieși în afara ecranului (dacă nu se folosește weight).

Structura internă

LinearLayout suprascrie onMeasure și onLayout din ViewGroup. La orientarea VERTICAL, onLayout plasează elementele pe axa Y: primul child — y=0, al doilea — y=prev.bottom + divider.hidden și așa mai departe. La HORIZONTAL — pe axa X. Divider (separatorul) se setează prin android:divider și android:showDividers (beginning, middle, end). Separatorul poate fi o culoare, un drawable sau o resursă Shape personalizată.

Orientare și Gravity: VERTICAL și HORIZONTAL

Orientarea — atributul cheie al LinearLayout care determină direcția de plasare a elementelor copil. android:orientation="vertical" aranjează elementele de sus în jos; android:orientation="horizontal" — de la stânga la dreapta (sau de la dreapta la stânga la localizarea RTL). Dacă orientarea nu este setată, implicit se folosește HORIZONTAL (pe versiunile vechi) — dar specificarea explicită este obligatorie pentru un comportament previzibil.

android:gravity — alinierea conținutului în interiorul LinearLayout. Acceptă combinații: top, bottom, left, right, center, center_horizontal, center_vertical, fill, clip_vertical, clip_horizontal. Valoarea gravity="center" pentru un layout VERTICAL va plasa toate elementele centrat pe orizontală. android:layout_gravity — atributul elementului copil care îl aliniază în interiorul LinearLayout părinte. Exemplu: un buton cu layout_gravity="right" într-un layout VERTICAL va fi lipit de marginea dreaptă.

Diferența: gravity — proprietatea părintelui (cum sunt dispuși copiii în interiorul său), layout_gravity — proprietatea copilului (cum se comportă în interiorul părintelui). Greșeala de a confunda aceste atribute este una dintre cele mai frecvente la începători.

Baseline alignment

Pentru layout-urile HORIZONTAL cu elemente text (TextView, Button, EditText) este util android:baselineAligned="true" — aliniază toate textele după linia de bază a fontului, indiferent de padding, size sau height. Acest lucru face ca un rând cu pictogramă, titlu și descriere să fie vizual îngrijit: textul nu sare în sus și în jos.

layout_weight: distribuirea greutății

layout_weight — atributul elementului copil al LinearLayout care determină ce parte din spațiul liber va ocupa. Funcționează doar în direcția orientării (lățimea pentru HORIZONTAL, înălțimea pentru VERTICAL). Formula de calcul: dimensiune = dimensiune proprie + (spațiu liber × (greutatea elementului / suma tuturor greutăților)). Spațiul liber = dimensiunea părintelui — suma tuturor dimensiunilor proprii ale copiilor.

layout_weight este mai eficient decât dimensiunile fixe pentru interfețe adaptive. De exemplu, dacă panoul din stânga trebuie să ocupe 30% din ecran, iar cel din dreapta — 70%, setați weight=3 și weight=7. Pentru o funcționare corectă, de obicei se setează dimensiunea în direcție la 0dp (android:layout_width="0dp" pentru HORIZONTAL), astfel dimensiunea proprie a elementului este considerată zero, iar întreaga dimensiune este determinată doar de weight. Aceasta este recomandarea standard Google (Android Developers Guide, 2024).

Important: greutățile se însumează pentru toate elementele din LinearLayout, inclusiv cele fără weight (greutatea lor este considerată 0). Dacă un element are weight=1, iar altul weight=2, primul va ocupa 1/3 din spațiul liber, al doilea — 2/3. weightSum (atributul părintelui) permite setarea sumei maxime a greutății — dacă greutățile copiilor în sumă sunt mai mici decât weightSum, diferența rămâne ca spațiu gol.

Exemple de cod: layout-uri XML

Exemplul 1: Formular vertical cu weight

Formularul de autentificare constă din trei elemente: câmpul email (ocupă 2/4), câmpul parolă (1/4) și butonul (1/4) din înălțimea ecranului. Toate cele trei elemente cu weight funcționează doar în orientarea VERTICAL pe înălțime.

xml
<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="Parolă"
        android:inputType="textPassword" />

    <Button
        android:id="@+id/login_button"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:text="Autentificare" />

</LinearLayout>

Înălțimea fiecărui element = (parent_height — padding) × (weight / sumWeights). email va primi 2/4 din înălțime, parola și butonul — câte 1/4. Toate height=0dp, deci dimensiunea proprie nu este luată în considerare — funcționează doar weight.

Exemplul 2: Bară de instrumente orizontală

Panou cu trei butoane: pictogramă înapoi (wrap_content), titlu (fill restul) și pictogramă meniu (wrap_content). weight pentru titlu = 1, butoanele fără weight.

xml
<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="Titlu"
        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>

Butoanele înapoi și meniu ocupă exact cât este necesar pentru pictogramă. Titlul (TextView) cu width=0dp și weight=1 se întinde pe tot spațiul rămas între ele. gravity="center_vertical" aliniază toate elementele pe centrul vertical.

Exemplul 3: LinearLayout-uri încuibate pentru o carte complexă

Cartea produsului: rând orizontal (imagine + bloc vertical de text). LinearLayout exterior HORIZONTAL, interior — VERTICAL pentru titlu, descriere și preț.

xml
<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="Denumirea produsului"
            android:textStyle="bold"
            android:textSize="16sp" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Descrierea scurtă a produsului în două rânduri"
            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>

Imaginea în stânga (80×80dp), în dreapta — bloc vertical din trei rânduri de text. LinearLayout interior are weight=1, deci ocupă tot spațiul rămas după imagine. Acesta este un model clasic de card de listă, întâlnit în mii de aplicații.

Problema încuibării și alternative

Principalul dezavantaj al LinearLayout — necesitatea containerelor încuibate pentru layout-uri complexe. Dacă trebuie să plasați elemente într-o rețea 2×2 sau să faceți un rând cu aliniere la două margini, sunt necesare cel puțin 2–3 niveluri de încuibare. Fiecare nivel de LinearLayout adaugă 2 treceri onMeasure, ceea ce pe dispozitivele slabe duce la blocări vizibile la randare.

Conform Android Performance Blog (Google, 2017), fiecare nivel suplimentar de încuibare crește timpul de layout cu 30–50 μs. Pentru o listă de 20 de elemente cu 3 niveluri de încuibare, întârzierea poate ajunge la 3 ms per element — acesta este un jank vizibil la derulare. ConstraintLayout rezolvă această problemă printr-o ierarhie plată, înlocuind 3–4 LinearLayout-uri încuibate cu un singur container cu constrângeri.

Recomandare: folosiți LinearLayout pentru layout-uri liniare simple (până la 10 elemente, un nivel de încuibare). Pentru carduri de listă, formulare cu aliniere diferită și ecrane cu structură tabelară, alegeți ConstraintLayout. Pentru elemente repetitive în RecyclerView, folosiți ConstraintLayout în fișierul layout al elementului — acest lucru este esențial pentru performanța derulării.

Întrebări frecvente

De ce nu funcționează layout_weight?

Cea mai frecventă cauză — nu este setată dimensiunea în direcție la 0dp. Pentru un layout HORIZONTAL este necesar android:layout_width="0dp", pentru VERTICAL — android:layout_height="0dp". Dacă elementul are wrap_content sau match_parent, weight poate să nu funcționeze sau să dea un rezultat neașteptat. A doua cauză — weightSum pe părinte este mai mic decât suma weight-urilor copiilor. A treia — utilizarea match_parent pe un element copil în direcția opusă.

Care este diferența dintre layout_weight și weightSum?

layout_weight se setează pe fiecare element copil și determină cota sa din spațiul liber. weightSum — atributul părintelui LinearLayout care setează suma maximă a greutăților. Implicit, weightSum = suma tuturor layout_weight ale copiilor. Dacă setați weightSum = 3, iar copiii cu weight=1, fiecare va ocupa 1/3. Dacă sunt doar doi copii cu weight=1, 1/3 rămasă va fi goală. weightSum este convenabil pentru fixarea proporțiilor fără recalculare la adăugarea/eliminarea elementelor.

Cum elimin spațiile dintre elementele LinearLayout?

Implicit nu există spații — elementele sunt plasate una lângă alta. Dacă au apărut spații, verificați: android:divider și android:showDividers pe părinte, android:layout_margin pe elementele copil. Suplimentar poate influența android:weightSum — dacă elementele folosesc weight, între ele poate rămâne spațiu gol din cauza unui calcul incorect. Pentru spații zero, setați tuturor copiilor margin=0dp și eliminați divider.

Ce este mai rapid: LinearLayout sau ConstraintLayout?

Pentru layout-uri simple unidirecționale (1–5 elemente pe rând/coloană) LinearLayout este puțin mai rapid — nu consumă resurse pentru calcularea constrângerilor. Pentru layout-uri complexe (mai mult de 5 elemente, rețele, diferite tipuri de aliniere) ConstraintLayout este mai rapid, deoarece folosește o ierarhie plată în loc de LinearLayout-uri încuibate. Conform testelor Google (Android Performance Blog), ConstraintLayout câștigă pe layout-uri care necesită 3+ niveluri de încuibare LinearLayout.

Concluzii

  • LinearLayout — ViewGroup de bază Android pentru plasarea secvențială a elementelor vertical sau orizontal.
  • Orientarea — android:orientation="vertical" (coloană) sau "horizontal" (rând) determină direcția layout-ului.
  • layout_weight — mecanism de distribuire a spațiului liber proporțional cu greutatea elementelor cu dimensiuni în 0dp.
  • Gravity — android:gravity (alinierea copiilor în interiorul părintelui) vs android:layout_gravity (alinierea copilului în părinte).
  • Încuibarea — principalul dezavantaj: pentru layout-uri complexe sunt necesare 2–3 niveluri, ceea ce încetinește randarea cu 30–50 μs pe nivel.
  • Alegerea — LinearLayout pentru rânduri/coloane simple (până la 10 elemente), ConstraintLayout pentru layout-uri complexe.
  • Adaptabilitatea — combinația weight + 0dp + baseline alignment acoperă 80% din sarcinile de layout liniar.

Vom dezvolta o aplicație mobilă la cheie

IT Sectr creează aplicații iOS și Android pentru startup-uri și afaceri din 2017. Vă vom consilia și vă vom propune cea mai bună soluție.

Discutați proiectul

Citiți și