Ipinapaliwanag namin ang mga batayan ng LinearLayout — pangunahing ViewGroup sa Android SDK para sa pag-align ng mga child element sa isang linya: patayo (LinearLayout.VERTICAL) o pahalang (LinearLayout.HORIZONTAL). Ang LinearLayout ay nananatiling pinakasimple at pinakamabilis na paraan upang bumuo ng isang hilera ng mga pindutan, listahan ng mga setting o form ng pag-input, kapag ang pagiging kumplikado ng layout ay hindi lalampas sa 5–10 elemento. Ang mga attribute na layout_weight at orientation ay namamahala sa pamamahagi ng espasyo at direksyon. Detalyadong detalye — sa LinearLayout API Reference.
Mga pangunahing puntos
LinearLayout — isa sa mga unang ViewGroup sa Android SDK (API Level 1), na idinisenyo para sa sunud-sunod na paglalagay ng mga child element sa isang hilera o kolum. Ang bawat bagong elemento ay inilalagay pagkatapos ng nauna, at ang direksyon ay itinakda ng attribute na android:orientation. Ang LinearLayout ay ang pinakasimple at pinaka-predictable na container ng Android, na ginagawa itong perpektong pagpili para sa mga linear na interface: mga hilera ng pindutan, mga listahan ng setting na may icon at teksto, mga pahalang na menu.
Sa kasaysayan, ang LinearLayout ay ang unang ViewGroup na nakikilala ng isang baguhang Android developer. Ang kalamangan nito ay transparency: ang mga child element ay inilalagay nang mahigpit sa pagkakasunud-sunod ng deklarasyon, nang walang nakatagong mga panuntunan sa pagpoposisyon. Hindi tulad ng RelativeLayout, kung saan ang isang elemento ay maaaring nakatali sa anumang kapitbahay, o ConstraintLayout na may sistema ng mga hadlang, ang LinearLayout ay gumagana sa prinsipyong 'una sa kaliwa/itaas, pangalawa pagkatapos nito, pangatlo pagkatapos ng pangalawa'. Ayon sa Google I/O 2017, 78% ng mga screen sa top 1000 Google Play app ay gumagamit ng LinearLayout bilang pangunahing o pantulong na container.
Ang pangunahing sukatan ng LinearLayout — LinearLayout.MeasureSpec — sistema ng pamamahala ng laki. Sa orientasyong VERTICAL, ang lapad ng bawat elemento ay katumbas ng lapad ng magulang (match_parent o fixed), at ang taas ay tinutukoy ng nilalaman o attribute. Para sa HORIZONTAL baligtad: taas katumbas ng magulang, lapad — batay sa nilalaman. Kung sa isang HORIZONTAL na hilera ang kabuuang lapad ng mga elemento ay lumampas sa lapad ng magulang, ang mga elemento ay maaaring lumabas sa screen (kung hindi ginagamit ang weight).
Ang LinearLayout ay nag-o-override ng onMeasure at onLayout mula sa ViewGroup. Sa orientasyong VERTICAL, inilalagay ng onLayout ang mga elemento sa Y axis: unang child — y=0, pangalawa — y=prev.bottom + divider.hidden, at iba pa. Sa HORIZONTAL — sa X axis. Ang Divider (paghihiwalay) ay itinakda sa pamamagitan ng android:divider at android:showDividers (beginning, middle, end). Ang paghihiwalay ay maaaring kulay, drawable, o custom na Shape resource.
Oryentasyon — ang pangunahing attribute ng LinearLayout na tumutukoy sa direksyon ng paglalagay ng mga child element. android:orientation="vertical" nag-aayos ng mga elemento mula sa itaas pababa; android:orientation="horizontal" — mula kaliwa pakanan (o kanan pakaliwa sa RTL localization). Kung hindi nakatakda ang oryentasyon, bilang default ay ginagamit ang HORIZONTAL (sa mas lumang bersyon) — ngunit ang tahasang pagtukoy ay kinakailangan para sa predictable na pag-uugali.
android:gravity — pag-align ng nilalaman sa loob ng LinearLayout. Tumatanggap ng mga kumbinasyon: top, bottom, left, right, center, center_horizontal, center_vertical, fill, clip_vertical, clip_horizontal. Ang halagang gravity="center" para sa VERTICAL layout ay ilalagay ang lahat ng elemento na naka-center nang pahalang. android:layout_gravity — attribute ng child element na nag-a-align nito sa loob ng magulang na LinearLayout. Halimbawa: isang pindutan na may layout_gravity="right" sa VERTICAL layout ay idiin sa kanang gilid.
Pagkakaiba: gravity — pag-aari ng magulang (kung paano inilalagay ang mga bata sa loob nito), layout_gravity — pag-aari ng bata (kung paano ito kumikilos sa loob ng magulang). Ang pagkakamali ng pagkalito sa mga attribute na ito ay isa sa pinakakaraniwan sa mga nagsisimula.
Para sa mga HORIZONTAL layout na may mga elementong tekstwal (TextView, Button, EditText) ay kapaki-pakinabang ang android:baselineAligned="true" — ina-align nito ang lahat ng teksto batay sa baseline ng font, anuman ang kanilang padding, size o height. Ginagawa nitong biswal na maayos ang isang hilera na may icon, pamagat at paglalarawan: ang teksto ay hindi tumatalon pataas at pababa.
layout_weight — attribute ng child element ng LinearLayout na tumutukoy kung anong bahagi ng libreng espasyo ang sasakupin nito. Gumagana lamang sa direksyon ng oryentasyon (lapad para sa HORIZONTAL, taas para sa VERTICAL). Formula ng pagkalkula: laki = sariling laki + (libreng espasyo × (timbang ng elemento / kabuuan ng lahat ng timbang)). Libreng espasyo = laki ng magulang — kabuuan ng lahat ng sariling laki ng mga bata.
Ang layout_weight ay mas mahusay kaysa sa mga nakapirming laki para sa mga adaptibong interface. Halimbawa, kung ang kaliwang panel ay dapat sumakop ng 30% ng screen at ang kanang panel — 70%, itakda ang weight=3 at weight=7. Para sa tamang paggana, karaniwang itinatakda ang laki sa direksyon sa 0dp (android:layout_width="0dp" para sa HORIZONTAL), kung gayon ang sariling laki ng elemento ay itinuturing na zero, at ang buong laki ay tinutukoy lamang ng weight. Ito ang karaniwang rekomendasyon ng Google (Android Developers Guide, 2024).
Mahalaga: ang mga timbang ay pinagsama-sama para sa lahat ng elemento sa LinearLayout, kabilang ang mga walang weight (ang kanilang timbang ay itinuturing na 0). Kung ang isang elemento ay may weight=1 at ang isa ay weight=2, ang una ay sasakop ng 1/3 ng libreng espasyo, ang pangalawa — 2/3. Ang weightSum (attribute ng magulang) ay nagpapahintulot sa pagtatakda ng maximum na kabuuan ng timbang — kung ang mga timbang ng mga bata sa kabuuan ay mas mababa kaysa weightSum, ang pagkakaiba ay nananatili bilang walang laman na espasyo.
Ang form ng pag-login ay binubuo ng tatlong elemento: field ng email (sumasakop ng 2/4), field ng password (1/4) at pindutan (1/4) ng taas ng screen. Lahat ng tatlong elemento na may weight ay gumagana lamang sa VERTICAL na oryentasyon ayon sa taas.
<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="Password"
android:inputType="textPassword" />
<Button
android:id="@+id/login_button"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:text="Mag-login" />
</LinearLayout>
Taas ng bawat elemento = (parent_height — padding) × (weight / sumWeights). Ang email ay makakakuha ng 2/4 ng taas, password at pindutan — tig-1/4. Lahat ng height=0dp, kaya ang sariling laki ay hindi isinasaalang-alang — tanging weight ang gumagana.
Panel na may tatlong pindutan: icon ng bumalik (wrap_content), pamagat (fill ang natitira) at icon ng menu (wrap_content). weight para sa pamagat = 1, mga pindutan na walang 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="Pamagat"
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>
Ang mga pindutan ng bumalik at menu ay sumasakop nang eksakto kung gaano karaming kailangan para sa icon. Ang pamagat (TextView) na may width=0dp at weight=1 ay umaabot sa lahat ng natitirang espasyo sa pagitan nila. gravity="center_vertical" ina-align ang lahat ng elemento sa patayong gitna.
Card ng produkto: pahalang na hilera (imahe + patayong bloke ng teksto). Panlabas na LinearLayout HORIZONTAL, panloob — VERTICAL para sa pamagat, paglalarawan at presyo.
<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="Pangalan ng produkto"
android:textStyle="bold"
android:textSize="16sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Maikling paglalarawan ng produkto sa dalawang linya"
android:textSize="14sp"
android:textColor="@color/gray" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="1 299 kuskusin."
android:textSize="18sp"
android:textColor="@color/accent" />
</LinearLayout>
</LinearLayout>
Imahe sa kaliwa (80×80dp), sa kanan — patayong bloke ng tatlong linya ng teksto. Ang panloob na LinearLayout ay may weight=1, kaya sinasakop nito ang lahat ng natitirang espasyo pagkatapos ng imahe. Ito ay isang klasikong pattern ng list card na matatagpuan sa libu-libong mga app.
Pangunahing disadvantage ng LinearLayout — ang pangangailangan para sa mga nested container para sa kumplikadong layout. Kung kailangan mong maglagay ng mga elemento sa isang 2×2 grid o gumawa ng isang hilera na may pagkakahanay sa dalawang gilid, kinakailangan ang hindi bababa sa 2–3 antas ng pagsasanib. Ang bawat antas ng LinearLayout ay nagdaragdag ng 2 pass ng onMeasure, na sa mahihinang device ay humahantong sa kapansin-pansing lag sa pag-render.
Ayon sa Android Performance Blog (Google, 2017), ang bawat karagdagang antas ng pagsasanib ay nagpapataas ng oras ng layout ng 30–50 μs. Para sa isang listahan ng 20 elemento na may 3 antas ng pagsasanib, ang pagkaantala ay maaaring umabot sa 3 ms bawat elemento — ito ay kapansin-pansing jank habang nag-i-scroll. Niresolba ng ConstraintLayout ang problemang ito sa pamamagitan ng flat hierarchy, na pinapalitan ang 3–4 na nested na LinearLayout ng isang container na may mga hadlang.
Rekomendasyon: gamitin ang LinearLayout para sa mga simpleng linear na layout (hanggang 10 elemento, isang antas ng pagsasanib). Para sa mga list card, form na may iba't ibang pagkakahanay at screen na may istrakturang tabular, piliin ang ConstraintLayout. Para sa mga umuulit na elemento sa RecyclerView, gamitin ang ConstraintLayout sa layout file ng elemento — ito ay mahalaga para sa pagganap ng pag-scroll.
Mga madalas itanong
Pinakakaraniwang dahilan — hindi nakatakda ang laki sa direksyon sa 0dp. Para sa HORIZONTAL layout kailangan ang android:layout_width="0dp", para sa VERTICAL — android:layout_height="0dp". Kung ang elemento ay may wrap_content o match_parent, ang weight ay maaaring hindi gumana o magbigay ng hindi inaasahang resulta. Pangalawang dahilan — ang weightSum sa magulang ay mas mababa kaysa kabuuan ng weight ng mga bata. Pangatlo — paggamit ng match_parent sa isang child element sa kabaligtaran na direksyon.
layout_weight ay itinakda sa bawat child element at tinutukoy ang bahagi nito sa libreng espasyo. weightSum — attribute ng magulang na LinearLayout na nagtatakda ng maximum na kabuuan ng mga timbang. Bilang default, weightSum = kabuuan ng lahat ng layout_weight ng mga bata. Kung itatakda mo ang weightSum = 3 at mga batang may weight=1, ang bawat isa ay sasakop ng 1/3. Kung dalawa lang ang batang may weight=1, ang natitirang 1/3 ay magiging walang laman. Ang weightSum ay maginhawa para sa pag-aayos ng mga proporsyon nang walang muling pagkalkula kapag nagdaragdag/nag-aalis ng mga elemento.
Bilang default walang mga puwang — ang mga elemento ay inilalagay nang magkatabi. Kung may lumitaw na mga puwang, suriin: android:divider at android:showDividers sa magulang, android:layout_margin sa mga child element. Dagdag pa, maaaring makaapekto ang android:weightSum — kung gumagamit ang mga elemento ng weight, maaaring manatili ang walang laman na espasyo sa pagitan ng mga ito dahil sa maling pagkalkula. Para sa zero na mga puwang, itakda ang lahat ng bata ng margin=0dp at alisin ang divider.
Para sa mga simpleng one-direction na layout (1–5 elemento sa hilera/kolum) Ang LinearLayout ay bahagyang mas mabilis — hindi ito gumagamit ng mga mapagkukunan sa pagkalkula ng mga hadlang. Para sa mga kumplikadong layout (higit sa 5 elemento, mga grid, iba't ibang uri ng pagkakahanay) Ang ConstraintLayout ay mas mabilis dahil gumagamit ito ng flat hierarchy sa halip na mga nested na LinearLayout. Ayon sa mga pagsubok ng Google (Android Performance Blog), nananalo ang ConstraintLayout sa mga layout na nangangailangan ng 3+ antas ng nested na LinearLayout.
Buod
Gagawa kami ng mobile application na turnkey
Gumagawa ang IT Sectr ng mga iOS at Android application para sa mga startup at negosyo mula noong 2017. Magpapayo kami sa iyo at magmumungkahi ng pinakamahusay na solusyon.
Basahin din