I chorak · Mobil dasturlash
Layoutlar
Elementlarni ekranda joylashtiramiz
I chorak · Mobil dasturlash
Elementlarni ekranda joylashtiramiz
Ushbu darsdan keyin siz:
wrap_content, match_parent yoki dp bilan bera
olasiz;O'tgan darsda activity_main.xml faylini topdik va undagi yozuvni
strings.xml ga ko'chirdik. Lekin faylning o'zi — ekranning tuzilishi —
hali qorong'i edi. Bugun aynan shu faylni ochamiz.
Har bo'limda avval o'zingiz qilib ko'rasiz, keyin nima bo'lganini sxemada ko'rasiz, oxirida qoidasini o'qiysiz.
| Nima | Izoh |
|---|---|
| Android Studio | 01-darsda o'rnatilgan |
SalomNukus loyihasi |
01–02-darslarda ishlagan loyiha |
| Emulyator | 01-darsda yasalgan virtual telefon |
Loyiha yo'q bo'lsa, 01-darsning 3-bo'limiga qaytib yangi loyiha yarating: Empty Views Activity, til Kotlin, Minimum SDK API 24.
Bu darsda activity_main.xml ni bir necha marta butunlay
almashtiramiz. Har safar to'liq kod beriladi — nusxa olib, faylning
eski matni o'rniga qo'yasiz. 2-darsda yozgan strings.xml va
colors.xml ga tegmaymiz, ular joyida qoladi.
Matnlarni vaqtincha to'g'ridan-to'g'ri yozamiz (android:text="Salom!").
Android Studio bunday qatorga sariq ogohlantirish qo'yadi:
Hardcoded string "Salom!", should use @string resource. Bu xato emas —
2-darsdagi @string qoidasini eslatmoqda. Haqiqiy ilovada matn
strings.xml ga ko'chiriladi; bu darsda esa layoutning o'ziga e'tibor
qaratish uchun qisqa yozamiz.
Android Studio versiyalari biroz farq qiladi. Tugma nomlari va joylashuvi sizda boshqacha bo'lishi mumkin, XML kodi esa bir xil ishlaydi.
app → res → layout → activity_main.xml ni oching.
Oynaning o'ng yuqori burchagida uchta tugma bor: Code, Split, Design. Code ni tanlang — faylning XML matni ochiladi.
Faylning butun matnini (Ctrl + A) quyidagi kod bilan almashtiring:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:id="@+id/salom"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#FFD54F"
android:text="Salom!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
Run bosing. Ekran o'rtasida sariq fonli kichik Salom! yozuvi
chiqadi.
Endi TextView dagi android:layout_width="wrap_content" ni
android:layout_width="match_parent" ga o'zgartiring va yana
Run bosing.
Kenglikni wrap_content ga qaytaring, android:background qatorining
tagiga android:padding="16dp" qatorini qo'shing va Run bosing.
Pastdagi app:layout_constraint... qatorlariga hozircha tegmang — ular
yozuvni o'rtada ushlab turadi, 3-bo'limda tushuntiramiz.
Skrinshot kutilmoqdaEmulyatorda match_parent kenglikdagi sariq yozuv
Tekshirib ko'ring: to'rtinchi qadamda sariq fon faqat so'zni o'rab turdi. Beshinchi qadamda u ekranning chap chetidan o'ng chetigacha cho'zildi — yozuv esa chapga surildi. Oltinchi qadamda sariq quti yana kichraydi, lekin matn atrofida bo'sh joy paydo bo'ldi.
Ekrandagi har bir element — to'g'ri to'rtburchak quti. Odatda uning
chegarasi ko'rinmaydi; biz background bilan bo'yab, uni ko'rinadigan
qildik.
Qutilar ikki xil bo'ladi:
TextView, keyinroq
Button, ImageView. Uning ichiga boshqa element qo'yilmaydi.ConstraintLayout — shunday
quti.Faylning eng tashqi tegi — ildiz layout — butun ekranni egallaydi,
chunki uning kengligi ham, balandligi ham match_parent. TextView
esa uning ichida, ota-quti — ConstraintLayout — bergan joyda
turibdi.
Tajribada uch xil o'lchamni ko'rdingiz:
wrap_content — quti ichidagisiga moslashdi: so'z qancha joy
olsa, shuncha.match_parent — quti ota-qutini to'ldirdi: butun kenglik.padding — quti ichkaridan kengaydi: matn va chegara orasida
bo'sh joy paydo bo'ldi. 16dp padding har tomondan qo'shiladi,
shuning uchun quti eni ham, bo'yi ham 32dp ga kattalashdi.Yozuv nega ekranning eng tepasidan boshlanmaydi? Shablondagi
MainActivity.kt da shunday qator bor:
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets ->
Bu kod ildiz layoutni R.id.main nomi bo'yicha topadi va unga soat,
batareya va pastki chiziq balandligicha ichki joy (padding) beradi. Shu
tufayli elementlar tizim panellari ostida qolib ketmaydi. Demak ildiz
layoutdagi android:id="@+id/main" qatori bezak emas — uni
o'chirsangiz, loyiha yig'ilmay qoladi.
Har bir element uchun ikkita o'lcham majburiy:
android:layout_width="..."
android:layout_height="..."
Ular uch xil qiymat oladi:
| Qiymat | Ma'nosi | Qachon |
|---|---|---|
wrap_content |
ichidagi matn yoki rasmga moslashadi | yozuv, tugma — o'z hajmida |
match_parent |
ota-qutini to'liq egallaydi | butun kenglikdagi sarlavha, fon |
160dp |
aniq o'lcham | rasm, belgi — qat'iy o'lchamda |
dp nima? Telefonlarning ekrani har xil zichlikda bo'ladi: bir
xil kattalikdagi ekranga birida kam, birida ko'p nuqta (piksel)
joylashadi. Agar o'lchamni pikselda bersak, zich ekranda element mitti
bo'lib qoladi. dp (density-independent pixel) esa zichlikka
moslashadi: 160dp hamma telefonda taxminan bir xil jismoniy kattalikda
ko'rinadi.
piksel = dp × zichlik / 160
Masalan, 480 zichlikli emulyatorda 1dp = 3 piksel. Uning ekrani
1280 piksel keng, ya'ni 1280 / 3 ≈ 427dp.
padding va margin — ikkalasi ham bo'sh joy, lekin boshqa-boshqa
tomonda:
| Atribut | Qayerda | Fon rangi |
|---|---|---|
android:padding |
chegara ichida, matn atrofida | bo'yaladi |
android:layout_margin |
chegara tashqarisida, qo'shni qutigacha | bo'yalmaydi |
Faqat bitta tomonga ham berish mumkin: paddingTop, paddingStart,
layout_marginBottom, layout_marginEnd va hokazo. Start — chap
tomon, End — o'ng tomon (arabcha kabi o'ngdan chapga yoziladigan
tillarda ular o'rin almashadi, shuning uchun Android Left/Right
o'rniga shu nomlarni tavsiya qiladi).
layout_ bilan boshlanadigan atributlar ota-qutiga qaratilgan.
layout_width, layout_margin, layout_weight — bular "meni qanday
joylashtir" degan iltimos, va uni ota-quti bajaradi. background,
padding, text esa elementning o'zi uchun.
LinearLayout — eng oddiy layout: elementlarni bitta chiziq bo'ylab, navbat bilan teradi. Ustun yoki qator — boshqa hech narsa.
activity_main.xml ning butun matnini quyidagi kod bilan
almashtiring. Diqqat qiling: ildiz teg endi LinearLayout, lekin
android:id="@+id/main" joyida qoldi.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
<TextView
android:id="@+id/birinchi"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#FFD54F"
android:padding="8dp"
android:text="Birinchi" />
<TextView
android:id="@+id/ikkinchi"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#81C784"
android:padding="8dp"
android:text="Ikkinchi" />
<TextView
android:id="@+id/uchinchi"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#64B5F6"
android:padding="8dp"
android:text="Uchinchi" />
</LinearLayout>
Run bosing.
android:orientation="vertical" ni android:orientation="horizontal"
ga o'zgartiring va yana Run bosing.
Endi har uchala TextView da android:layout_width="wrap_content"
ni ikki qatorga almashtiring:
android:layout_width="0dp"
android:layout_weight="1"
Run bosing.
Skrinshot kutilmoqdaEmulyatorda layout_weight bilan teng bo'lingan uchta yozuv
Tekshirib ko'ring: ikkinchi qadamda uchta rangli yozuv ustma-ust, chap chetda turdi. Uchinchi qadamda ular bir qatorga tizildi, o'ng tomonda bo'sh joy qoldi. Beshinchi qadamda esa uchalasi ekran kengligini teng uchga bo'lib oldi.
LinearLayout elementlarni fayldagi tartibda, birin-ketin teradi.
Qaysi yo'nalishda terishini android:orientation aytadi:
vertical — har bir keyingi element oldingisining tagiga;horizontal — har bir keyingi element oldingisining o'ng
tomoniga.Oxirgi o'zgarishda boshqa narsa bo'ldi. Kenglik 0dp bo'lganda element
o'zi uchun joy talab qilmaydi. LinearLayout avval bo'sh joyni
hisoblaydi, keyin uni layout_weight qiymatlariga qarab bo'lib beradi.
Uchalasida 1 — demak har biriga 1 / 3.
Nisbatni o'zgartirish mumkin. Vaznlar 2, 1, 1 bo'lsa, jami 4
ulush: birinchisi 2/4 — ekranning yarmi, qolgan ikkitasi 1/4 dan.
| Atribut | Kimga yoziladi | Nima qiladi |
|---|---|---|
android:orientation |
LinearLayout ga |
vertical — ustun, horizontal — qator |
android:layout_weight |
ichidagi elementga | bo'sh joydan olinadigan ulush |
android:gravity |
LinearLayout ga |
ichidagilar guruhini qayerga surish |
orientation yozilmasa — horizontal bo'ladi. Bu sukut bo'yicha
qiymat. Ustun kutib, orientation ni unutsangiz, hamma element bitta
qatorga tiziladi.
layout_weight bilan kenglikni 0dp qiling (ustunda — balandlikni).
Aks holda element avval o'z matniga joy oladi va vazn faqat qolgan
joyni bo'ladi. Natijada qutilar deyarli teng chiqadi-yu, lekin aynan
teng bo'lmaydi: uzunroq so'zli quti biroz kengroq bo'ladi.
Qatorda bitta element match_parent bo'lsa, u butun kenglikni
egallaydi va undan keyingi elementlarga joy qolmaydi — ular ekranda
umuman ko'rinmaydi.
android:gravity guruhni ota-quti ichida suradi:
| Qiymat | Qayerga |
|---|---|
top, bottom |
tepaga, pastga |
start, end |
chapga, o'ngga |
center_horizontal |
gorizontal o'rtaga |
center_vertical |
vertikal o'rtaga |
center |
ikkala yo'nalishda o'rtaga |
Ikki qiymatni | belgisi bilan birlashtirish mumkin: top|end — o'ng
yuqori burchak.
<LinearLayout
...
android:orientation="vertical"
android:gravity="center">
Bu kodda uchta yozuv ekranning qoq o'rtasiga, ustma-ust holda to'planadi.
LinearLayout qachon qulay? Elementlar oddiy ro'yxat yoki qator
bo'lib tursa: sozlamalar ro'yxati, uchta teng tugma, "rasm — yozuv"
qatori. Joylashuv murakkablashsa — bir element pastda, biri o'ngda,
biri boshqasiga yopishgan — ConstraintLayout kerak bo'ladi.
Yangi loyihada activity_main.xml ning ildizi aynan ConstraintLayout
bo'ladi. Unda element navbat bilan terilmaydi: har bir elementning
joyi bog'lanishlar bilan beriladi.
activity_main.xml ning butun matnini quyidagi kod bilan
almashtiring:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:id="@+id/markaz"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#81C784"
android:padding="8dp"
android:text="Markaz"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/yonida"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:background="#64B5F6"
android:padding="8dp"
android:text="Yonida"
app:layout_constraintStart_toEndOf="@id/markaz"
app:layout_constraintTop_toTopOf="@id/markaz" />
<TextView
android:id="@+id/burchak"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="20dp"
android:background="#FFD54F"
android:padding="8dp"
android:text="Burchak"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
Run bosing.
Endi yonida yozuvidan app:layout_constraintStart_toEndOf="@id/markaz"
qatorini o'chiring va yana Run bosing.
Skrinshot kutilmoqdaEmulyatorda markazga, yoniga va burchakka bog'langan yozuvlar
Tekshirib ko'ring: ikkinchi qadamda yashil Markaz ekranning qoq
o'rtasida, ko'k Yonida uning o'ng tomonida, sariq Burchak esa pastki
o'ng burchakda chiqdi. Uchinchi qadamda Yonida o'z joyidan ketib,
ekranning chap chetiga yopishdi — lekin balandligi o'zgarmadi.
Shu bilan birga Android Studio bu elementni xato deb belgiladi. Ogohlantirish matni shunday:
This view is not constrained horizontally: at runtime it will jump to the left unless you add a horizontal constraint
Ilova baribir yig'ildi va ishga tushdi — bu ogohlantirish "natija siz kutgandek chiqmaydi" degani. O'chirilgan qatorni qaytarib qo'ying.
Har bir bog'lanishni rezina bog'ich deb tasavvur qiling. U elementning bir tomonini boshqa narsaning tomoniga tortib turadi.
Markaz to'rt tomondan ota-qutiga bog'langan. Chapdan va o'ngdan
bir xil kuch bilan tortilgani uchun gorizontal o'rtada, tepadan va
pastdan tortilgani uchun vertikal o'rtada turibdi.Yonida ning chap tomoni (Start) Markaz ning o'ng tomoniga
(End) bog'langan, tepasi esa Markaz ning tepasiga. Shuning uchun
u doim Markaz ning yonida yuradi — Markaz ko'chsa, u ham ko'chadi.Burchak faqat pastga va o'ngga tortilgan — shu burchakka borib
yopishdi. 20dp margin uni chetdan biroz uzoqlashtiradi.Uchinchi qadamda Yonida gorizontal bog'ichini yo'qotdi. Uni chapga
ham, o'ngga ham hech narsa tortmay qoldi va ConstraintLayout uni
chap chetga qo'ydi. Vertikal bog'ich esa joyida edi, shuning uchun
balandligi saqlandi.
Design rejimidagi joy — faqat Studio uchun. Elementni Design
oynasida sichqoncha bilan surib qo'ysangiz, Studio unga
tools:layout_editor_absoluteX degan qator yozadi. tools: bilan
boshlanadigan qatorlar faqat Studio'dagi ko'rinish uchun: telefonda ular
umuman o'qilmaydi. Bog'lanishsiz element telefonda chap yuqori
burchakka sakraydi.
Bog'lanish atributining nomi uch bo'lakdan iborat:
app:layout_constraint Start _to EndOf ="@id/markaz"
↑ ↑ ↑
mening tomonim uning tomoni kimga
To'rt tomon bor: Top (tepa), Bottom (past), Start (chap),
End (o'ng). Qiymat — parent (ota-quti) yoki boshqa elementning
@id/... nomi.
| Atribut | Ma'nosi |
|---|---|
Top_toTopOf="parent" |
tepasi ekran tepasiga |
Bottom_toBottomOf="parent" |
pasti ekran pastiga |
Start_toStartOf="parent" |
chap cheti ekran chap chetiga |
End_toEndOf="parent" |
o'ng cheti ekran o'ng chetiga |
Top_toBottomOf="@id/a" |
a ning tagiga |
Bottom_toTopOf="@id/a" |
a ning ustiga |
Start_toEndOf="@id/a" |
a ning o'ng tomoniga |
End_toStartOf="@id/a" |
a ning chap tomoniga |
(Jadvalda qisqalik uchun har bir nomning boshidagi
app:layout_constraint tushirib qoldirilgan.)
Asosiy qoida: har bir element kamida bitta vertikal (Top yoki
Bottom) va bitta gorizontal (Start yoki End) bog'lanishga ega
bo'lsin. Aks holda:
| Nima yetishmaydi | Telefonda qayerga tushadi | Studio ogohlantirishi |
|---|---|---|
| gorizontal bog'lanish | chap chetga | This view is not constrained horizontally |
| vertikal bog'lanish | tepaga | This view is not constrained vertically |
| ikkalasi ham | chap yuqori burchakka | This view is not constrained |
Qarama-qarshi ikki tomon bog'lansa, element o'rtada turadi.
Start_toStartOf="parent" va End_toEndOf="parent" — gorizontal
o'rta; Top_toTopOf va Bottom_toBottomOf — vertikal o'rta.
Boshqa elementga bog'lash uchun uning id si bo'lishi shart.
@+id/markaz — nom yaratiladi (plyus bilan, elementning o'zida).
@id/markaz — tayyor nomga murojaat qilinadi (bog'lanishda).
app: bilan boshlanadigan atributlar uchun ildiz tegda
xmlns:app="http://schemas.android.com/apk/res-auto" qatori bo'lishi
kerak. ConstraintLayout shablonida u bor.
Margin faqat bog'langan tomonda ishlaydi. Margin — bu bog'ichning
uzunligi. Elementda faqat Top_toTopOf="parent" bo'lib, unga
android:layout_marginStart="60dp" bersangiz, u baribir chap chetda
qoladi: chap tomonni hech narsa tortmayapti, demak masofani o'lchaydigan
bog'ich ham yo'q.
Bog'lanishni Design rejimida sichqoncha bilan ham yasash mumkin:
element tanlanganda uning tomonlarida kichik doirachalar chiqadi, ularni
ekran chetiga yoki boshqa elementga tortsangiz, Studio kerakli
app:layout_constraint... qatorini o'zi yozadi. Qaysi yo'l bilan
yasamang, oxirida Code rejimida natijani tekshiring — bu darsda biz
XML'ni o'qishni o'rganyapmiz.
| Xato | Nima ko'rinadi | Sabab | Yechim |
|---|---|---|---|
| Loyiha yig'ilmadi | Unresolved reference 'main'. |
ildiz tegdan android:id="@+id/main" o'chirilgan |
ildiz tegga android:id="@+id/main" ni qaytaring |
| Hamma element bir qatorda | ustun kutilgan edi | android:orientation yozilmagan |
android:orientation="vertical" qo'shing |
| Qatordagi elementlar yo'qoldi | faqat birinchisi ko'rinadi | birinchisining kengligi match_parent |
wrap_content yoki 0dp + layout_weight |
| Qutilar teng bo'lmadi | vazn bor, lekin kengliklar har xil | kenglik wrap_content qolgan |
kenglikni 0dp qiling |
| Element chap yuqoriga sakradi | Studio'da bir joyda, telefonda boshqa joyda | bog'lanish yo'q | vertikal va gorizontal bog'lanish qo'shing |
| Element chap chetga yopishdi | This view is not constrained horizontally |
Start yoki End bog'lanishi yo'q |
gorizontal bog'lanish qo'shing |
| Loyiha yig'ilmadi | error: resource id/markz ... not found. |
bog'lanishdagi @id/... nomi xato yozilgan |
elementning android:id bilan harfma-harf solishtiring |
| Loyiha yig'ilmadi | Resource compilation failed va AttributePrefixUnbound |
ildiz tegda xmlns:app qatori yo'q |
ildiz tegga xmlns:app="http://schemas.android.com/apk/res-auto" qo'shing |
| Ilova ochilishi bilan yopildi | Studio pastidagi Logcat oynasida You must supply a layout_width attribute. |
elementda layout_width yoki layout_height yozilmagan |
ikkala o'lchamni ham yozing |
| Margin ishlamadi | element joyidan qimirlamadi | shu tomonda bog'lanish yo'q | avval shu tomonga bog'lanish qo'shing |
| Sariq ogohlantirish | Hardcoded string "...", should use @string resource |
matn to'g'ridan-to'g'ri yozilgan | xato emas; haqiqiy ilovada strings.xml ga ko'chiring |
| O'zgarish ko'rinmadi | emulyatorda eski ekran | fayl saqlanib, Run bosilmagan | Ctrl + S, keyin Run |
background bilan chegarasini ko'rish mumkinlayout_width va layout_height — majburiy: wrap_content, match_parent yoki dp1dp = 3 pikselpadding — ichkari (fon bilan), layout_margin — tashqari (fonsiz)android:id="@+id/main" ni o'chirmang — MainActivity.kt unga murojaat qiladiLinearLayout: vertical — ustun, horizontal — qator; sukut — horizontal0dp + layout_weightgravity — ichidagilar guruhini surish: center, bottom, end, top|endConstraintLayout: app:layout_constraint<Mening>_to<Uning>Of="parent | @id/nom"Bu darsda ikki topshiriq bor, ikkalasi ham shu qo'llanmadagi materialdan chiqadi:
LinearLayout ga almashtirib, uchta yozuvni sizga berilgan
yo'nalishda, o'lchamda va joyda terish.Topshiriq matni shu sahifaning pastida — jurnaldagi raqamingizni tanlaganingizdan keyin chiqadi. Har kimda o'z yozuvlari, o'z nisbati va o'z joyi bo'ladi.
Har ikkala topshiriqda ham ildiz tegdagi android:id="@+id/main"
qatori qolsin. Uni o'chirsangiz, loyiha yig'ilmaydi.
Skrinshot qanday olinadi? Win + Shift + S bosing, kerakli qismni
belgilang, so'ng Word yoki Paint'ga Ctrl + V bilan qo'ying. Emulyator
oynasida fotoapparat belgili tugma (Take Screenshot) ham bor — u
telefon ekranining o'zini rasmga oladi. Kod skrinshotida fayl nomi ham
ko'rinib tursin.
Endi elementlarni ekranda joylashtira olamiz. Lekin hozircha ekranda faqat yozuv bor — uni bosib ham, unga matn kiritib ham bo'lmaydi.
Keyingi darsda amaliy mashg'ulot bo'ladi — bugungi uchta tushuncha mashq qilinadi. Undan keyin Button, EditText va TextView bilan tanishib, ekranni jonlantira boshlaymiz.
Ro'yxatdagi tartib raqamingizni tanlang — shaxsiy topshiriq shu yerda chiqadi. Bir marta tanlaysiz, brauzer eslab qoladi.