11 β Hamma narsa widget¶
β¬ οΈ Oldingi: 10 β Flutter bilan tanishuv Β· π README Β· Keyingi: 12 β Layout I: Row, Column, Flex β‘οΈ
Bu bobda: o'tgan bobda "hamma narsa widget" g'oyasini eshitdingiz. Endi uni chuqur o'rganamiz. Avval nega widget bunday ishlashini tushunamiz: widget β ekranning bir bo'lagining o'zgarmas tavsifi, va ular bir-birining ichiga joylashib daraxt hosil qiladi. Keyin o'zingizning
StatelessWidgetingizni βSalomKartasini β noldan yozamiz:buildmetodi,constkonstruktor, maydonlar (konfiguratsiya),super.key. So'ng eng ko'p ishlatiladigan ko'rinish widgetlarini birma-bir ko'ramiz:TextvaTextStyle,Icon,Image, va Flutter'ning shveytsariya pichog'i βContainer(uningpadding/margin/decorationqatlamlari bilan).SizedBox,Padding,Centerham shu yerda. Oxirida hamma narsani birlashtirib, chiroyli profil kartasini quramiz va eng muhim ko'nikmani β kompozitsiya (kichik widgetlarni bir-birining ichiga joylash) β o'zlashtiramiz. Holat (state) bilan ishlash, ya'ni vaqt o'tishi bilan o'zgaradigan widgetlar, esa 16-bobda keladi.
Widget aslida nima?¶
O'tgan bobda widgetni "ekranning bir bo'lagini tasvirlaydigan element" deb atadik. Endi bitta nozik, lekin juda muhim narsani aytamiz:
Widget β bu ekranning emas, balki ekran qanday ko'rinishi kerakligining tavsifidir.
Bu farqni tushunish Flutter'ni tushunishning kalitidir. Tasavvur qiling, siz uy quruvchiga chizma (loyiha) berasiz. Chizmaning o'zi uy emas β u shunchaki uy qanday bo'lishi kerakligining qog'ozdagi tavsifi. Quruvchi chizmaga qarab haqiqiy uyni quradi. Widget β ana shu chizma; haqiqiy "uy"ni (ekrandagi piksellarni) esa Flutter quradi.
Bundan ikkita muhim xulosa kelib chiqadi:
- Widget β o'zgarmas (immutable). Chizmani chizib bo'lgach, uni o'chirmaysiz β yangi chizma chizasiz. Xuddi shunday, widget bir marta yaratilgach, uning ichidagi qiymatlar o'zgarmaydi. Agar ekran boshqacha ko'rinishi kerak bo'lsa, Flutter yangi widget yaratadi. Aynan shuning uchun widget maydonlari odatda
finalbo'ladi. - Widget β arzon. Widget shunchaki tavsif (oddiy Dart obyekti) bo'lgani uchun, uni yaratish va tashlab yuborish juda tez. Flutter sekundiga ko'p marta yangi widgetlar yaratadi β bu normal holat.
π‘ Eslatma β "o'zgarmas" deganda nima nazarda tutilyapti? Widgetning o'zi o'zgarmaydi degani. Lekin ekran umuman o'zgarmaydi degani emas: holat o'zgarganda Flutter eski widgetni tashlab, yangisini quradi. Ya'ni o'zgarish β widgetni tahrirlash orqali emas, almashtirish orqali bo'ladi. Buni 16-bobda chuqur ko'ramiz.
Widgetlar daraxtga birlashadi¶
Bitta widget kamdan-kam yolg'iz turadi. Odatda widgetlar bir-birining ichiga joylashadi: Centerning ichida Text, Scaffoldning ichida AppBar va body... Shunday qilib widget daraxti hosil bo'ladi β xuddi oila daraxti kabi: bitta ildiz, uning bolalari, ularning bolalari va hokazo.
Bu daraxtni siz kodingiz tuzilishi orqali quryapsiz. Qachonki bitta widgetni boshqasining child: yoki children: qismiga yozsangiz, aslida daraxtga shox qo'shyapsiz:
Center( // ildiz (bu bo'lakda)
child: Container( // uning bolasi
child: Text('Salom'), // uning bolasi (barg)
),
)
Bu daraxt β Center β Container β Text. Flutter mana shu tuzilmani o'qiydi va ekranga chizadi. Sizning vazifangiz β to'g'ri daraxtni tasvirlash, qolganini Flutter qiladi.
StatelessWidget β o'zgarmas ko'rinish¶
Widgetlar ikki katta turga bo'linadi:
StatelessWidget(holatsiz) β ko'rinishi faqat kirish ma'lumotiga (konfiguratsiyasiga) bog'liq, vaqt o'tishi bilan o'zi o'zgarmaydi. Masalan, "Salom, Anvar!" deb yozadigan karta β agar ism o'zgarmasa, karta ham o'zgarmaydi.StatefulWidget(holatli) β ichida o'zgaradigan holat bor; foydalanuvchi tugma bossa yoki ma'lumot kelsa, u o'zini yangilab turadi. Masalan, hisoblagich yoki "yoqtirish" tugmasi.
Bu bobda biz faqat birinchisi β StatelessWidget bilan ishlaymiz. Bu eng oddiy va eng ko'p ishlatiladigan tur. Holatli widgetlarni keyingiroq, 16-bobda, shoshilmasdan o'rganamiz.
StatelessWidgetni shunday tasavvur qiling: u funksiya kabi ishlaydi. Unga kirish (ism, rang, matn) berasiz, u sizga UI (widget daraxti) qaytaradi. Bir xil kirish β har doim bir xil chiqish. Hech qanday "yashirin" o'zgaruvchi yo'q.
Birinchi o'z widgetingiz: SalomKartasi¶
Endi nazariyani amalda ko'ramiz. O'zimizning StatelessWidgetimizni yozamiz β u ism qabul qilib, salomlashuvchi karta ko'rsatadi:
import 'package:flutter/material.dart';
class SalomKartasi extends StatelessWidget {
final String ism; // maydon = konfiguratsiya (o'zgarmas kirish)
const SalomKartasi({super.key, required this.ism});
@override
Widget build(BuildContext context) {
return Container(
padding: const EdgeInsets.all(16),
child: Text('Salom, $ism!'),
);
}
}
Har bir qatorni tushunamiz β bu naqshni Flutter'da minglab marta yozasiz:
class SalomKartasi extends StatelessWidgetβStatelessWidgetdan meros olib (07-bobdagiextendsesingizdami?), o'z widgetimizni e'lon qilyapmiz.final String ism;β bu maydon (field). U widgetning konfiguratsiyasi β tashqaridan beriladigan kirish ma'lumoti.finalbo'lgani muhim: widget o'zgarmas, demak maydonlari ham o'zgarmaydi.const SalomKartasi({super.key, required this.ism});β konstruktor.constβ bu widget o'zgarmas qiymatlardan tuzilishi mumkinligini bildiradi (10-bobda nega muhimligini ko'rgandik: Flutter uni qayta ishlatadi, tezroq bo'ladi).{super.key, required this.ism}β jingalak qavs ichidagi nomli parametrlar (04-bob).super.keyβ har bir widgetga beriladigan ixtiyoriy kalit (Flutter undan daraxtdagi widgetlarni ajratishda foydalanadi β hozircha shunchaki yozib qo'ying).required this.ismβismni majburiy qiladi va uniismmaydoniga joylaydi (07-bobdagithis.xqisqa shakli).Widget build(BuildContext context)β bu eng muhim metod. U widget daraxtini qaytaradi. Bu yerda uContainerichidaTextqaytaryapti.ismmaydonini'Salom, $ism!'ichida ishlatyapmiz.
Endi bu widgetni ishlatamiz β uni boshqa widget ichiga oddiygina yozamiz:
Bir marta yozdik, istalgancha ishlatamiz β har safar boshqa ism bilan. Mana shu β widgetni qayta ishlatish (reuse)ning go'zalligi.
π‘ Nega o'z widgetimni yozaman, hammasini bitta katta
buildichiga yozsam bo'lmaydimi? Texnik jihatdan bo'ladi. Lekin ilova kattalashganda bittabuildmetodi yuzlab qatordan iborat, o'qib bo'lmaydigan "dev"ga aylanadi. Takrorlanadigan yoki mantiqan bir butun bo'lgan bo'laklarni alohida widgetga ajratish β kodni toza, qayta ishlatiladigan va tushunarli qiladi. Buni bob oxirida amalda ko'ramiz.
Text va TextStyle β matnni ko'rsatish va bezash¶
Eng oddiy va eng ko'p ishlatiladigan widget β Text. U ekranga matn chiqaradi:
Lekin matnning ko'rinishini (o'lcham, rang, qalinlik) sozlash uchun unga style: parametrida TextStyle beramiz:
Text(
'Sarlavha',
style: TextStyle(
fontSize: 24, // shrift o'lchami
fontWeight: FontWeight.bold, // qalinlik
color: Color(0xFF027DFD), // rang
letterSpacing: 0.5, // harflar orasidagi masofa
fontStyle: FontStyle.italic, // qiya (kursiv)
),
)
fontSizeβ shrift o'lchami (mantiqiy piksellarda).fontWeightβ qalinlik:FontWeight.normal,FontWeight.bold, yoki aniqFontWeight.w300...w900.colorβ matn rangi. Tayyor ranglar (Colors.red,Colors.blue) yoki o'zingizniki (Color(0xFF027DFD)β0xFFto'liq shaffof emaslik, qolgani RRGGBB).fontStyle,letterSpacing,height(qatorlar orasidagi masofa) va boshqalar.
Uzun matn ekranga sig'masa nima bo'ladi? Buni maxLines va overflow boshqaradi:
Text(
'Bu juda uzun matn bo\'lib, ekranga to\'liq sig\'masligi mumkin...',
maxLines: 2, // ko'pi bilan 2 qator
overflow: TextOverflow.ellipsis, // ortig'ini "..." bilan kesadi
textAlign: TextAlign.center, // matnni markazga tekislaydi
)
maxLinesβ matn nechta qatorgacha cho'zilishi mumkinligi.overflowβ sig'magan qism bilan nima qilish:TextOverflow.ellipsis(oxiriga...qo'yadi),.clip(shartta kesadi),.fade(asta yo'qoladi).textAlignβ matnni tekislash:.left,.center,.right,.justify.
π‘ Mavzulangan (themed) matn. Har safar
fontSize,colorni qo'lda yozish o'rniga, ilovaning umumiy mavzusidan tayyor matn uslublarini olishingiz mumkin:Theme.of(context).textTheme.titleLarge,.bodyMediumva hokazo. Bu butun ilova bo'ylab matnni bir xil va izchil qiladi. Mavzular vaTheme.of(context)haqida kitobning keyingi qismida β Material 3 bobida β batafsil gaplashamiz. HozirchaTextStyleni qo'lda yozish yetarli.
Icon β tayyor belgilar¶
Icon widget ekranga belgi (piktogramma) chiqaradi: yurakcha, yulduzcha, sozlama g'ildiragi va minglab boshqalar. Material kutubxonasida tayyor ikonkalar Icons. ichida turadi:
Icons.favorite,Icons.star,Icons.home,Icons.settings,Icons.searchβIcons.dan keyin yozishni boshlasangiz, muharrir (VS Code) qolganini taklif qiladi. Minglab ikonka bor.colorvasizeβ rang va o'lcham (fontSizekabi mantiqiy piksellarda).
Ikonkalar tugmalar, ro'yxat elementlari, holat ko'rsatkichlari (masalan "tasdiqlangan" uchun Icons.check_circle) uchun juda ko'p ishlatiladi.
Image β rasm ko'rsatish¶
Rasmni ekranga chiqarish uchun Image widget bor. Rasm qayerdan kelishiga qarab ikkita asosiy usul mavjud.
Internetdan (Image.network):
Ilova ichidagi fayldan (Image.asset):
Image.asset ishlashi uchun rasmni avval pubspec.yamlda ro'yxatdan o'tkazish kerak (paketlarni ro'yxatdan o'tkazganday). Aks holda Flutter rasmni topolmaydi:
Foydali parametrlar:
fit: BoxFit.coverβ rasm berilgan maydonni to'liq qoplaydi (kerak bo'lsa chetlarini kesib). Boshqa variantlar:BoxFit.contain(to'liq sig'diradi, bo'sh joy qolishi mumkin),BoxFit.fill(cho'zib to'ldiradi β nisbat buzilishi mumkin).width/heightβ rasm o'lchami.errorBuilderβ rasm yuklanmasa (masalan internet uzilsa) nima ko'rsatish:
Image.network(
url,
errorBuilder: (context, error, stackTrace) =>
const Icon(Icons.broken_image, size: 48),
)
loadingBuilderβ rasm internetdan yuklanayotganda (masalan aylanuvchi indikator) nima ko'rsatish. Tarmoq rasmlari uchun foydali.
π‘ Hozir
errorBuilder/loadingBuilderning to'liq sintaksisini yodlash shart emas. Asosiysini eslab qoling: internetdan kelgan rasm yuklanmasligi yoki sekin kelishi mumkin, vaImage.networksizga bu holatlarni chiroyli boshqarish imkonini beradi.
Container β shveytsariya pichog'i¶
Container β Flutter'da eng ko'p ishlatiladigan widgetlardan biri. U ko'p maqsadli quti: bitta bolasini (child) o'rab oladi va unga bo'shliq, fon, chegara, soya β istalganini qo'sha oladi. Aynan shuning uchun uni "shveytsariya pichog'i" deyishadi.
Containerni tushunish uchun uning qatlamlarini bilish kerak. Tashqaridan ichkariga: margin β border β padding β child:
Container(
margin: const EdgeInsets.all(12), // tashqi bo'sh joy (qo'shnilardan uzoq)
padding: const EdgeInsets.all(16), // ichki bo'sh joy (child'ni chetdan uzoq)
width: 200,
height: 80,
alignment: Alignment.center, // child'ni ichida qayerga joylash
color: Colors.blue, // oddiy fon rangi
child: const Text('Ichidagi matn'),
)
padding va margin β EdgeInsets¶
padding (ichki bo'shliq) va margin (tashqi bo'shliq) qiymatlari EdgeInsets orqali beriladi. Uning bir necha qulay shakli bor:
EdgeInsets.all(16) // har to'rt tomondan 16
EdgeInsets.symmetric(horizontal: 24, vertical: 8) // chap/o'ng 24, yuqori/past 8
EdgeInsets.only(left: 16, top: 8) // faqat tanlangan tomonlardan
paddingβ quti chegarasi bilan ichidagichildorasidagi bo'shliq.marginβ quti chegarasi bilan tashqaridagi qo'shni widgetlar orasidagi bo'shliq.
Buni "matnni qutiga joylash" deb tasavvur qiling: padding β matn bilan qutining ichki devori orasidagi bo'shliq; margin β quti bilan boshqa qutilar orasidagi bo'shliq.
color vs decoration β muhim qoida¶
Oddiy fon rangi kerak bo'lsa, color: yetarli. Lekin yumaloq burchaklar, chegara, soya yoki gradient kerak bo'lsa β decoration: BoxDecoration(...) ishlatasiz:
Container(
padding: const EdgeInsets.all(20),
decoration: BoxDecoration(
color: Colors.white, // fon rangi (decoration ichida!)
borderRadius: BorderRadius.circular(16), // yumaloq burchaklar
border: Border.all(color: Colors.blue, width: 2), // chegara
boxShadow: [
BoxShadow(
color: Colors.black.withValues(alpha: 0.1), // yengil soya
blurRadius: 12,
offset: const Offset(0, 4),
),
],
),
child: const Text('Bezatilgan quti'),
)
β οΈ Diqqat β ko'p uchraydigan xato!
color:vadecoration:ni bir vaqtda bermang β Flutter xato beradi. Sababi oddiy: rang allaqachondecorationichida (BoxDecoration(color: ...)) belgilanadi. Demak,decorationishlatsangiz, rangni ham uning ichiga yozing, tashqaridagicolor:ni emas.
BoxDecorationning asosiy imkoniyatlari: color (fon), borderRadius (yumaloq burchak), border (chegara), boxShadow (soya), gradient (rang o'tishi). Ular bilan oddiy Containerdan chiroyli karta yasash mumkin.
SizedBox, Padding, Center β kichik, lekin kerakli¶
Bu uchta kichik widget juda tez-tez ishlatiladi.
SizedBox β aniq o'lchamli quti, yoki ko'pincha shunchaki bo'sh joy (oraliq) qo'yish uchun:
SizedBox(height: 16) // 16 piksel balandlikdagi vertikal oraliq
SizedBox(width: 8) // 8 piksel kenglikdagi gorizontal oraliq
SizedBox(width: 100, height: 100, child: ...) // aniq o'lchamli quti
Esingizdami β bo'sh joy ham widget. Column yoki Row ichida elementlar orasiga oraliq qo'yish uchun SizedBoxdan ko'p foydalanasiz.
Padding β faqat bolasiga bo'shliq qo'shadi (boshqa hech narsa qilmaydi):
π‘
PaddingvsContainerpadding'i. Ikkalasi ham bo'shliq qo'shadi. Agar sizga faqat bo'shliq kerak bo'lsa (rang, chegara, o'lcham kerak emas) β soddaPaddingishlating, u "niyatingizni" aniqroq ko'rsatadi. Rang/chegara ham kerak bo'lsa βContainerqulayroq, chunki hammasi bitta joyda.
Center β bolasini ota maydonining markaziga joylaydi (10-bobda ko'rgandingiz):
Kompozitsiya β kichik bo'laklardan murakkab UI¶
Endi eng muhim ko'nikmaga keldik. Flutter'da murakkab interfeysni bitta ulkan widget bilan emas, balki ko'plab kichik widgetlarni bir-birining ichiga joylash bilan quriladi. Buni kompozitsiya (composition) deyiladi β Lego'dagidek, kichik bo'laklardan katta narsa yig'asiz.
Keling, hamma o'rgangan narsani birlashtirib, profil kartasini quramiz: Container (quti) ichida Column (ustun), uning ichida rasm, ism, lavozim va pastda "Faol" belgisi (Icon + Text):
import 'package:flutter/material.dart';
class ProfilKartasi extends StatelessWidget {
final String ism;
final String lavozim;
final String rasmUrl;
const ProfilKartasi({
super.key,
required this.ism,
required this.lavozim,
required this.rasmUrl,
});
@override
Widget build(BuildContext context) {
return Container(
width: 240,
padding: const EdgeInsets.all(20),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(20),
boxShadow: [
BoxShadow(
color: Colors.black.withValues(alpha: 0.08),
blurRadius: 16,
offset: const Offset(0, 6),
),
],
),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
// 1. Yumaloq avatar (rasm)
ClipOval(
child: Image.network(
rasmUrl,
width: 88,
height: 88,
fit: BoxFit.cover,
errorBuilder: (context, error, stack) =>
const Icon(Icons.person, size: 88),
),
),
const SizedBox(height: 12),
// 2. Ism
Text(
ism,
style: const TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
),
const SizedBox(height: 4),
// 3. Lavozim
Text(
lavozim,
style: const TextStyle(fontSize: 13, color: Colors.grey),
),
const SizedBox(height: 16),
// 4. "Faol" belgisi β Row ichida Icon + Text
Row(
mainAxisSize: MainAxisSize.min,
children: const [
Icon(Icons.check_circle, color: Colors.green, size: 18),
SizedBox(width: 6),
Text('Faol', style: TextStyle(color: Colors.green)),
],
),
],
),
);
}
}
Ishlatish:
const ProfilKartasi(
ism: 'Anvar Aliyev',
lavozim: 'Flutter dasturchisi',
rasmUrl: 'https://example.com/anvar.jpg',
)
Bu karta aslida shunday widget daraxtini quradi β chap tomonda ekranda ko'ringani, o'ng tomonda kod tuzilishi:
Diqqat qiling β bizda yangi tanishlar bor:
Columnβ bolalarini ustun qilib (yuqoridan pastga) joylaydi;Rowβ qator qilib (chapdan o'ngga). Bularni keyingi 12-bobda batafsil o'rganamiz.mainAxisSize: MainAxisSize.minβ ustun/qator faqat bolalariga yetadigancha joy egallashini bildiradi.ClipOvalβ bolasini (rasmni) doira shaklida kesadi β yumaloq avatar shunday yasaladi.- Elementlar orasidagi
SizedBoxlar β vertikal oraliqlar.
Mana shu β kompozitsiya: rasm, matn, ikonka kabi kichik, oddiy widgetlardan, ularni Container va Column/Row ichiga joylab, butun bir chiroyli karta qurdik. Hech bir widget murakkab emas β murakkablik ularning birikishidan tug'iladi.
π‘ Yaxshi odat β widgetlarni ajrating. Yuqorida butun kartani bitta
ProfilKartasiwidgetiga ajratdik. Endi uni istalgan joyda, istalgan ma'lumot bilan qayta ishlatishimiz mumkin. Agar karta yana ham murakkablashsa, masalan "Faol" belgisini ham alohidaHolatBelgisiwidgetiga ajratish mumkin edi. Qoida:buildmetodingiz juda uzayib ketsa yoki bir bo'lak takrorlanayotgan bo'lsa β uni alohida widgetga ajrating. Bu kodni o'qish va saqlashni osonlashtiradi.
Keyingi qadam¶
Tabriklaymiz β endi siz Flutter'ning yuragini tushunasiz: widget β ekranning o'zgarmas tavsifi, ular daraxtga birlashadi, va siz o'z StatelessWidgetlaringizni yozib, ularni kompozitsiya orqali murakkab UI'ga yig'asiz. Text, Icon, Image, Container, SizedBox, Padding, Center β eng ko'p ishlatiladigan ko'rinish widgetlari endi qo'lingizda.
Lekin bir narsani sezgan bo'lsangiz kerak: Column va Rowni shunchaki "his qildik", chuqur tushunmadik. Keyingi 12-bobda aynan joylashuv (layout) β Row, Column, Flex, ularning tekislash (alignment) va cho'zilish (Expanded) qoidalari β bilan jiddiy shug'ullanamiz. So'ngra, vaqt o'tishi bilan o'zgaradigan widgetlar β holat (state), setState β 16-bobda keladi.
Mashqlar¶
Har bir mashqni o'zingiz yozib,
flutter runbilan ishga tushirib ko'ring. Avval yechimsiz urinib ko'ring, keyin<details>ichidagi yechimga qarang.
Oson¶
- O'z so'zlaringiz bilan tushuntiring: "widget β o'zgarmas tavsif" iborasi nimani anglatadi? Chizma va uy o'xshatishini ishlating.
StatelessWidgetvaStatefulWidgetfarqi nimada? Qaysi biri "vaqt o'tishi bilan o'zini yangilab turadi"?Containerdapaddingvamarginfarqini bir jumlada tushuntiring.- Nima uchun
Containergacolor:vadecoration:ni bir vaqtda berish xato? To'g'ri usul qanday?
O'rta¶
TashrifQogozinomliStatelessWidgetyozing: uismvakasb(ikkalaString) qabul qilsin.builddaContainerichidaColumnqaytarsin: yuqoridaism(katta, qalin matn), pastidakasb(kichikroq, kulrang matn).constkonstruktor vasuper.keyni unutmang.- Bezatilgan
Containeryozing: oq fon, 12 radiusli yumaloq burchaklar, ko'k chegara (width 2) va yengil soya. IchidaEdgeInsets.all(16)padding bilan "Salom" matni bo'lsin. - Bitta
Rowyarating: ichidaIcon(Icons.star, color: Colors.amber), keyin 8 piksel oraliq (SizedBox), keyinText('4.8 reyting')bo'lsin.
Qiyin¶
- 5-mashqdagi
TashrifQogozini kengaytiring: pastigaIcon+Textdan iborat "aloqa qatori" qo'shing (masalanIcons.email+ email manzili). Bu qatorni alohidaStatelessWidgetga (AloqaQatori, parametrlari:ikonkavamatn) ajrating va uniTashrifQogoziichida ishlating. Nima uchun bunday ajratish foydali ekanini bir jumlada izohlang.
Yechimlar
1. Widget ekranning o'zi emas β u ekran qanday ko'rinishi kerakligining tavsifi (xuddi uy chizmasi uydan farq qilganidek). Chizma β qog'ozdagi reja; haqiqiy uyni quruvchi quradi. Xuddi shunday, widget β Dart kodidagi tavsif; haqiqiy piksellarni Flutter chizadi. "O'zgarmas" degani: widgetni yaratgandan keyin uning qiymatlari o'zgarmaydi β ekran boshqacha bo'lishi kerak bo'lsa, Flutter eski widgetni tashlab yangisini quradi.
2. StatelessWidget β ko'rinishi faqat kirish (konfiguratsiya)ga bog'liq, vaqt o'tishi bilan o'zi o'zgarmaydi. StatefulWidget β ichida o'zgaradigan holat bor, foydalanuvchi harakati yoki yangi ma'lumot kelganda o'zini yangilab turadi. Vaqt o'tishi bilan o'zini yangilab turadigani β StatefulWidget.
3. padding β quti chegarasi bilan ichidagi child orasidagi ichki bo'shliq; margin β quti bilan tashqaridagi qo'shni widgetlar orasidagi bo'shliq.
4. Chunki fon rangi decoration (BoxDecoration) ichida ham belgilanadi β color:ni alohida berish ikki joyda ziddiyatga olib keladi, shuning uchun Flutter xato beradi. To'g'ri usul: decoration ishlatsangiz, rangni uning ichiga yozing β decoration: BoxDecoration(color: Colors.white, ...).
5.
import 'package:flutter/material.dart';
class TashrifQogozi extends StatelessWidget {
final String ism;
final String kasb;
const TashrifQogozi({super.key, required this.ism, required this.kasb});
@override
Widget build(BuildContext context) {
return Container(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
Text(
ism,
style: const TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
),
const SizedBox(height: 4),
Text(
kasb,
style: const TextStyle(fontSize: 14, color: Colors.grey),
),
],
),
);
}
}
6.
Container(
padding: const EdgeInsets.all(16),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(12),
border: Border.all(color: Colors.blue, width: 2),
boxShadow: [
BoxShadow(
color: Colors.black.withValues(alpha: 0.1),
blurRadius: 8,
offset: const Offset(0, 3),
),
],
),
child: const Text('Salom'),
)
7.
Row(
mainAxisSize: MainAxisSize.min,
children: const [
Icon(Icons.star, color: Colors.amber),
SizedBox(width: 8),
Text('4.8 reyting'),
],
)
8.
import 'package:flutter/material.dart';
// alohida ajratilgan, qayta ishlatiladigan widget
class AloqaQatori extends StatelessWidget {
final IconData ikonka;
final String matn;
const AloqaQatori({super.key, required this.ikonka, required this.matn});
@override
Widget build(BuildContext context) {
return Row(
mainAxisSize: MainAxisSize.min,
children: [
Icon(ikonka, size: 16, color: Colors.blue),
const SizedBox(width: 6),
Text(matn),
],
);
}
}
class TashrifQogozi extends StatelessWidget {
final String ism;
final String kasb;
final String email;
const TashrifQogozi({
super.key,
required this.ism,
required this.kasb,
required this.email,
});
@override
Widget build(BuildContext context) {
return Container(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
Text(
ism,
style: const TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
),
const SizedBox(height: 4),
Text(kasb, style: const TextStyle(fontSize: 14, color: Colors.grey)),
const SizedBox(height: 12),
AloqaQatori(ikonka: Icons.email, matn: email), // ajratilgan widget
],
),
);
}
}
Nima uchun foydali: "aloqa qatori" mantiqan bir butun (ikonka + matn) β uni alohida widgetga ajratsak, kodni qayta ishlatishimiz (masalan telefon raqami uchun ham AloqaQatori(ikonka: Icons.phone, ...)), build metodini qisqa va o'qilishli saqlashimiz mumkin.
β¬ οΈ Oldingi: 10 β Flutter bilan tanishuv Β· π README Β· Keyingi: 12 β Layout I: Row, Column, Flex β‘οΈ