Förklarar grunderna i LinearLayout — grundläggande ViewGroup i Android SDK för att justera underordnade element i en linje: vertikalt (LinearLayout.VERTICAL) eller horisontellt (LinearLayout.HORIZONTAL). LinearLayout förblir det enklaste och snabbaste sättet att bygga en rad knappar, en inställningslista eller ett inmatningsformulär, när layoutens komplexitet inte överstiger 5–10 element. Attributen layout_weight och orientation hanterar rumsfördelning och riktning. Detaljerad specifikation — i LinearLayout API Reference.
Huvudpunkter
LinearLayout — en av de första ViewGroup i Android SDK (API Level 1), avsedd för sekventiell placering av underordnade element i en rad eller kolumn. Varje nytt element placeras efter det föregående och riktningen bestäms av attributet android:orientation. LinearLayout är den enklaste och mest förutsägbara Android-behållaren, vilket gör den till ett idealiskt val för linjära gränssnitt: knapprader, inställningslistor med ikon och text, horisontella menyer.
Historiskt sett är LinearLayout den första ViewGroup som en nybörjare inom Android-utveckling stöter på. Dess fördel är transparens: underordnade element placeras strikt i deklarationsordning, utan dolda positioneringsregler. Till skillnad från RelativeLayout, där ett element kan kopplas till valfri granne, eller ConstraintLayout med dess begränsningssystem, fungerar LinearLayout enligt principen 'först till vänster/överst, andra efter det, tredje efter det andra'. Enligt Google I/O 2017 använder 78% av skärmarna i de 1000 mest populära Google Play-apparna LinearLayout som primär eller sekundär behållare.
Det viktigaste måttet för LinearLayout — LinearLayout.MeasureSpec — systemet för storlekshantering. Vid VERTICAL-orientering är bredden på varje element lika med förälderns bredd (match_parent eller fast) och höjden bestäms av innehållet eller attributet. För HORIZONTAL gäller motsatsen: höjden är lika med förälderns, bredden — baserat på innehåll. Om den totala bredden på elementen i en HORIZONTAL-rad överstiger förälderns bredd kan elementen hamna utanför skärmen (om weight inte används).
LinearLayout åsidosätter onMeasure och onLayout från ViewGroup. Vid VERTICAL-orientering placerar onLayout element på Y-axeln: första child — y=0, andra — y=prev.bottom + divider.hidden, och så vidare. Vid HORIZONTAL — på X-axeln. Divider (avskiljare) ställs in via android:divider och android:showDividers (beginning, middle, end). Avskiljaren kan vara en färg, drawable eller anpassad Shape-resurs.
Orientering — det viktigaste attributet för LinearLayout som bestämmer riktningen för placering av underordnade element. android:orientation="vertical" ordnar element uppifrån och ner; android:orientation="horizontal" — från vänster till höger (eller höger till vänster vid RTL-lokalisering). Om orientering inte är inställd används som standard HORIZONTAL (på äldre versioner) — men explicit angivelse är obligatorisk för förutsägbart beteende.
android:gravity — justering av innehåll inom LinearLayout. Accepterar kombinationer: top, bottom, left, right, center, center_horizontal, center_vertical, fill, clip_vertical, clip_horizontal. Värdet gravity="center" för en VERTICAL-layout placerar alla element centrerat horisontellt. android:layout_gravity — attribut för underordnat element som justerar det inom den överordnade LinearLayout. Exempel: en knapp med layout_gravity="right" i en VERTICAL-layout trycks mot högerkanten.
Skillnad: gravity — förälderns egenskap (hur barn placeras inuti), layout_gravity — barnets egenskap (hur det beter sig inuti föräldern). Felet att blanda ihop dessa attribut är ett av de vanligaste bland nybörjare.
För HORIZONTAL-layouter med textelement (TextView, Button, EditText) är android:baselineAligned="true" användbart — det justerar alla texter efter teckensnittets baslinje, oberoende av deras padding, size eller height. Detta gör en rad med ikon, titel och beskrivning visuellt snygg: texten hoppar inte upp och ner.
layout_weight — attribut för underordnat element i LinearLayout som bestämmer hur stor del av det fria utrymmet det ska ta upp. Fungerar endast i orienteringsriktningen (bredd för HORIZONTAL, höjd för VERTICAL). Beräkningsformel: storlek = egen storlek + (fritt utrymme × (elementets vikt / summan av alla vikter)). Fritt utrymme = förälderns storlek — summan av alla barns egna storlekar.
layout_weight är effektivare än fasta storlekar för adaptiva gränssnitt. Om den vänstra panelen till exempel ska ta upp 30% av skärmen och den högra panelen 70%, ställ in weight=3 och weight=7. För korrekt funktion ställs storleken i riktningen vanligtvis in på 0dp (android:layout_width="0dp" för HORIZONTAL), då anses elementets egen storlek vara noll och hela storleken bestäms endast av weight. Detta är Googles standardrekommendation (Android Developers Guide, 2024).
Viktigt: vikter summeras för alla element i LinearLayout, inklusive de utan weight (deras vikt anses vara 0). Om ett element har weight=1 och ett annat weight=2, tar det första upp 1/3 av det fria utrymmet, det andra — 2/3. weightSum (förälderns attribut) gör det möjligt att ställa in den maximala viktsumman — om barnens vikter totalt är mindre än weightSum, blir skillnaden kvar som tomt utrymme.
Inloggningsformuläret består av tre element: e-postfält (tar upp 2/4), lösenordsfält (1/4) och knapp (1/4) av skärmhöjden. Alla tre element med weight fungerar endast i VERTICAL-orientering på höjden.
<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="Lösenord"
android:inputType="textPassword" />
<Button
android:id="@+id/login_button"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:text="Logga in" />
</LinearLayout>
Höjd för varje element = (parent_height — padding) × (weight / sumWeights). E-post får 2/4 av höjden, lösenord och knapp — 1/4 var. Alla height=0dp, så egen storlek räknas inte — endast weight fungerar.
Panel med tre knappar: tillbaka-ikon (wrap_content), titel (fyll resten) och meny-ikon (wrap_content). weight för titel = 1, knappar utan weight.
<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="Titel"
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>
Knapparna tillbaka och meny tar upp precis så mycket utrymme som behövs för ikonen. Titeln (TextView) med width=0dp och weight=1 sträcker sig över allt återstående utrymme mellan dem. gravity="center_vertical" justerar alla element vertikalt centrerat.
Produktkort: horisontell rad (bild + vertikalt textblock). Yttre LinearLayout HORIZONTAL, inre — VERTICAL för titel, beskrivning och pris.
<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="Produktnamn"
android:textStyle="bold"
android:textSize="16sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Kort produktbeskrivning på två rader"
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>
Bild till vänster (80×80dp), till höger — vertikalt block med tre textrader. Det inre LinearLayout har weight=1, så det tar upp allt återstående utrymme efter bilden. Detta är ett klassiskt listkortsmönster som finns i tusentals appar.
Den största nackdelen med LinearLayout — behovet av nästlade behållare för komplexa layouter. Om du behöver placera element i ett 2×2-rutnät eller skapa en rad med justering mot två kanter krävs minst 2–3 nestningsnivåer. Varje LinearLayout-nivå lägger till 2 onMeasure-passager, vilket på svaga enheter leder till märkbara hackningar vid rendering.
Enligt Android Performance Blog (Google, 2017) ökar varje extra nestningsnivå layouttiden med 30–50 μs. För en lista med 20 element och 3 nestningsnivåer kan fördröjningen nå 3 ms per element — detta är märkbar jank vid scrollning. ConstraintLayout löser detta problem genom platt hierarki och ersätter 3–4 nästlade LinearLayout med en enda behållare med begränsningar.
Rekommendation: använd LinearLayout för enkla linjära layouter (upp till 10 element, en nestningsnivå). För listkort, formulär med olika justering och skärmar med tabellstruktur, välj ConstraintLayout. För återkommande element i RecyclerView, använd ConstraintLayout i elementets layoutfil — detta är avgörande för scrollprestanda.
Vanliga frågor
Den vanligaste orsaken — storleken i riktningen är inte inställd på 0dp. För HORIZONTAL-layout behövs android:layout_width="0dp", för VERTICAL — android:layout_height="0dp". Om elementet har wrap_content eller match_parent kan weight fungera fel eller ge oväntat resultat. Den andra orsaken — weightSum på föräldern är mindre än summan av barnens weight. Den tredje — användning av match_parent på ett underordnat element i motsatt riktning.
layout_weight ställs in på varje underordnat element och bestämmer dess andel av det fria utrymmet. weightSum — attribut för den överordnade LinearLayout som ställer in den maximala viktsumman. Som standard är weightSum = summan av alla barns layout_weight. Om du ställer in weightSum = 3 och barn med weight=1, tar varje upp 1/3. Om det bara finns två barn med weight=1 blir den återstående 1/3 tom. weightSum är praktiskt för att fixera proportioner utan omräkning vid tillägg/borttagning av element.
Som standard finns inga mellanrum — element placeras intill varandra. Om mellanrum har uppstått, kontrollera: android:divider och android:showDividers på föräldern, android:layout_margin på underordnade element. Dessutom kan android:weightSum påverka — om element använder weight kan tomt utrymme finnas kvar mellan dem på grund av felaktig beräkning. För noll mellanrum, ställ in alla barns margin=0dp och ta bort divider.
För enkla envägs-layouter (1–5 element i rad/kolumn) är LinearLayout något snabbare — det förbrukar inte resurser på att beräkna begränsningar. För komplexa layouter (mer än 5 element, rutnät, olika typer av justering) är ConstraintLayout snabbare eftersom det använder platt hierarki istället för nästlade LinearLayout. Enligt Googles tester (Android Performance Blog) vinner ConstraintLayout på layouter som kräver 3+ nestningsnivåer av LinearLayout.
Sammanfattning
Vi utvecklar en mobil applikation nyckelfärdigt
IT Sectr skapar iOS- och Android-applikationer för startups och företag sedan 2017. Vi ger dig råd och föreslår den bästa lösningen.
Läs också