π― μ€λμ λΆμ‘±ν μμ ― λΆλΆ κ°μλ₯Ό 볡μ΅νκ³ , ν·κ°λ¦¬κ±°λ μμ§ λͺ»νλ μ½λλ μμ ―μ μ°Ύμλ΄€λ€. velogμ μ 리νλ λ΄μ©λ λ€μ νμΈν΄λ³΄λ©΄μ μ§ννκ³ , λ΄μΌν νμ΅ κ³νλ κ°λ¨νκ² μΈμ λ€.
κ·Έλ¦¬κ³ μ€νμ Gitμ κΈ°λ³Έμ λν νΉκ°μ΄ μμ΄ λ€μλλ°, μμ μ νλ² μ€μΉνκ³ μ¨λ΄€λλ° κΈ°μ΅μ΄ μ μλμ μ½κ° μ΄λ €μ λ κ² κ°λ€.
π μμ ― 볡μ΅
1.Viewμμ ―
Β Β 1-1 PageView μμ ―
Β Β 1-2 ListView μμ ―
Β Β 1-3 GridView μμ ―
Β Β 1-4 TabBar μμ ―
2.
Layoutμμ ―
Β Β 2-1 Container μμ ―
Β Β 2-2 SizedBox μμ ―
Β Β 2-3 Row & Column μμ ―
Β Β 2-4 Expanded μμ ―
Β Β 2-5 Stack μμ ― & Positioned μμ ―
β μμ
Row( children: [ Expanded( child: Container(color: Colors.red, height: 100), ), Expanded( child: Container(color: Colors.green, height: 100), ), ], )β Flex κ³μ΄ μμ ―(
Row,Columnλ±)μchildμ€ νλλ‘ μ¬μ©λμ΄ λ¨μ 곡κ°μ μ°¨μ§νκ³ , flex κ°μ ν΅ν΄ λΉμ¨ μ‘°μ μ΄ κ°λ₯νκ² νλ€.
νλͺ© ExpandedFlexibleλ¨μ κ³΅κ° λ¬΄μ‘°κ±΄ κ½ μ±μ νμν λ§νΌλ§ μ±μ μμ μ ν μμμ΄ κ½ μ°¨μΌ ν¨ μμ ν¬κΈ°μ λ°λΌ μ μ°νκ² μ‘°μ κ°λ₯ κΈ°λ³Έ flex 1 1
νλͺ© childchildrenνμ λ¨μΌ μμ ― ( Widget)μμ ― 리μ€νΈ ( List<Widget>)λ» νλμ μμ μμ ― μ¬λ¬ κ°μ μμ μμ ―λ€ μ¬μ©μ² Container,Center,Expandedλ±Row,Column,Stackλ±
β
childβ νλμ μμλ§ λ°μ μ μμ λCenter( child: Text('Hello, Flutter!'), )β λ³΄ν΅ λ¨μΌ λ μ΄μμμΌ λ μ¬μ©λλλ°,
Centerλ μμμ΄ νλλ§ λ€μ΄κ° μ μμ΄μchildμμ±μ μ΄λ€.
β
childrenβ μ¬λ¬ μμμ νκΊΌλ²μ λ£μ λColumn( children: [ Text('Hello'), Text('Flutter'), Icon(Icons.star), ], )β
Columnμ μ¬λ¬ μμμ μΈλ‘λ‘ λ°°μΉνλκΉchildrenμ μ¨μΌνλ©°, 리μ€νΈλ‘ μ¬λ¬ μμ ―μ ν λ²μ λ£μ΄μ€μΌ ν΄μList<Widget>ννμ΄λ€.
<Widget>children: <Widget>[ Widget(), Widget(), ... ] // μλ μ 체 λ¬Έλ²β Dart λ¬Έλ²μμ
[ ]λ 리μ€νΈλ₯Ό λ»νλλ°,childrenμ΄List<Widget>νμ μ μꡬν λ κ·Έλ κ² μ°μΈλ€.
Β
π‘ Dart νΉμ±μListμWidgetλ€μ΄κ° μμΌλ©΄ μμμList<Widget>μΌλ‘ λ°μλ€μ΄κΈ°μ `` μ μλ΅ν μ μλ€.
μμ ― μ’ λ₯ childμ¬μ©childrenμ¬μ©Containerβ μ¬μ© κ°λ₯ β μ¬μ© λΆκ° Centerβ μ¬μ© κ°λ₯ β μ¬μ© λΆκ° Expandedβ μ¬μ© κ°λ₯ β μ¬μ© λΆκ° Rowβ μ¬μ© λΆκ° β μ¬λ¬ μμ νμ Columnβ μ¬μ© λΆκ° β μ¬λ¬ μμ νμ Stackβ μ¬μ© λΆκ° β μ¬λ¬ μμ νμ
π‘ μλ¬ λ©μμ§μ expected a Widget but got list<widget>μ΄ λμ€λ©΄,
childλ₯Ό μ¨μΌ νλλ°childrenμ μΌκ±°λ λ°λλ‘ μΌμ κ°λ₯μ±μ΄ ν¬λ€.
β μ€λ₯ ν΄κ²°
Widget build(BuildContext context) { return const MaterialApp("μ€λ₯ λ°μ μ 보ν΅
constλ₯Ό μ§μ°λ©΄ μ€λ₯κ° ν΄κ²°λλ€"κ³ λ°°μ λλ°, κ·Έ μ΄μ κ° λκΉ?
μ΄μ 1. β λ΄λΆμ
constλΆκ°λ₯ν μμ±μ΄ μμ λconst MaterialApp( title: 'My App', home: MyHomePage(), // β μ΄κ² λ¬Έμ μΌ μ μμ )
MyHomePage()κ°constκ° μλλ°, μ 체MaterialAppμconstλ‘ λ§λ€μκΈ° λλ¬Έμ΄λ€.
Β β μλ¬: "The constructor being called isn't a const constructor."
β ν΄κ²°: constλ₯Ό μ§μ°λ©΄ homeμ΄ constκ° μλμ΄λ OK!
μ΄μ 2. β
constλ‘ μ μΈνλλ° λ°λλ κ°μ λ£μμ λconst MaterialApp( theme: ThemeData(primarySwatch: Colors.blue), // μ΄κ² const μλ )
ThemeData(...)λ κΈ°λ³Έμ μΌλ‘ constκ° μλκΈ° λλ¬Έμ,constλ‘ λ§λ€λ©΄ μλ¬κ° λλ€.
β ν΄κ²°: constλ₯Ό μ§μ°λ©΄ themeκ° constκ° μλμ΄λ OK!
μν© μ€λͺ constλ₯Ό μ°λ©΄λ΄λΆμ μλ λͺ¨λ κ°λ const λ΄λΆ κ°μ΄ constκ° μλλ©΄ β μλ¬ λ°μ constλ₯Ό μ§μ°λ©΄λ΄λΆ μμ ―μ΄ λ³ν΄λ λλκΉ μλ¬ μμ
π― μΈμ constλ₯Ό μ¨μΌ ν κΉ?
κ°μ΄λ UIκ° κ³ μ μΌ λ, λ³νμ§ μλ μμ ―μΌ λ constλ₯Ό μ°λ©΄ μ±λ₯μ μ’λ€.const Text('κ³ μ ν μ€νΈ') // πText(DateTime.now().toString()) // β const λͺ» μ
μ©μ΄ μλ―Έ constλ³νμ§ μλ κ°μ²΄λ₯Ό μμ±ν λ μ¬μ©νλ ν€μλ const constructorκ·Έ κ°μ²΄λ₯Ό λ§λ€κΈ° μν΄ μ¬μ©νλ μμ±μ ν¨μκ° constλ‘ μ μΈλ κ²½μ° --
1οΈβ£const constructorμ μclass MyBox extends StatelessWidget { const MyBox({super.key}); // const constructor // Widget build(BuildContext context) { return Container(color: Colors.blue, width: 100, height: 100); } }2οΈβ£ constλ‘ κ°μ²΄ μμ±
const MyBox() // const constructorλ‘ const μ¬μ© κ°λ₯!β
constλ₯Ό μ°λ €λ©΄ ν΄λμ€μconst constructorκ° μ μλμ΄μΌνλ©°, κ·Έλ μ§ μμΌλ©΄MyWidget()μ΄λ κ² μ¨μΌ νκ³ , μ΅μ νλ μλλ€.
const constructor- λΆλ³ κ°μ²΄ λ§λ€ μ μλ μΌλ° μμ±μfactory constructor- κ°μ²΄λ₯Ό λ§λ€ λ μ§μ μμ±νμ§ μκ³ , 쑰건μ λ°λΌ κΈ°μ‘΄ κ±Έ μ¬μ¬μ©νκ±°λ λ€λ₯Έ λ°©μμΌλ‘ μμ±νλ μμ±μ- κ·Έκ±Έ
constλ‘ λ§λ€λ©΄? πconst factory constructor
β 보ν΅
constμμ±μλ λ¨μνκ² κ°μ²΄λ§ λ§λ€κ³ λμΈλ°,factoryλ κ°μ κ°μ κ°μ§ κ°μ²΄λ ν λ²λ§ λ§λ€κ³ κ³μ μ¬μ¬μ©νκ² νλ€κ±°λ, λ΄λΆμμ μΊμ±μ ν΄μ£Όλ μμ΄λ€.class ColorBox { final int color; static final Map<int, ColorBox> _cache = {}; // λ§λ κ°μ²΄λ₯Ό μΊμλ‘ μ μ₯ν΄λκΈ° μν Map // const ColorBox._internal(this.color); // μ§μ§ const μμ±μ // factory const ColorBox(int color) { return _cache.putIfAbsent(color, () => ColorBox._internal(color)); } // factory constructor }β μΈλΆμμ
const ColorBox(0xFF0000)μ΄λ κ² νΈμΆνλ©΄ λ΄λΆμμ μ΄λ―Έ λ§λ€μ΄λ κ°μ΄ μμΌλ©΄ κ·Έκ±Έ μ¬μ¬μ©νκ³ , μμΌλ©΄ μλ‘ λ§λ€κ³ μ μ₯νλ€.
ν€μλ μΈμ κ³ μ λ¨? μμ νΉμ§ finalλ°νμμ κ²°μ final name = getName();// μ€ν μ€μ κ²°μ ν λ²λ§ μ€μ κ°λ₯νμ§λ§ λμ€μ κ° μ ν΄μ Έλ OK constμ»΄νμΌ νμμ κ³ μ const age = 20;// μ½λ μμ±ν λλΆν° κ³ μ μμ μ½λμ μ¨μμ λλΆν° μμν μ λ³ν¨
β‘ μμ λΉκ΅
final now = DateTime.now(); // β κ°λ₯ β μ€νλ λ κ°μ΄ μ ν΄μ§ const now = DateTime.now(); // β μ€λ₯ β μ»΄νμΌ νμμ μ μ μμ
β‘ μ½λμμ
class MyWidget extends StatelessWidget { final String title; // β μ΄κ±΄ μΈλΆμμ κ° λ°μ μ μμ΄ // const MyWidget({super.key, required this.title}); // β const μμ±μ κ°λ₯! }β
titleμfinalμ΄μ§λ§ const μλ β ν λ² μ ν΄μ§λ©΄ λ
β μμ±μλconstλ‘ λ§λ€μ΄μ β λΆλ³ μμ ― λ§λ€ μ μμ
κ΅¬λΆ finalconstμμ κ°λ₯? β (ν λ²λ§ ν λΉ κ°λ₯) β (μμν κ³ μ ) κ°μ΄ μ ν΄μ§λ μμ λ°νμ μ»΄νμΌ νμ κ°μ²΄ μμ±μ μ¬μ© κ°λ₯? O O, λ¨ λ΄λΆ κ°λ λͺ¨λ constμ¬μΌ ν¨ μμ ―μμ μ£Όλ‘ μ°μ΄λ κ³³ ν΄λμ€ νλ λΆλ³ μμ ―, μ€νμΌ κ° λ±
π‘ ν
finalβ λ³κ²½ λΆκ°ν νλ (μ£Όμ λ°μ κ° λ±)
constβ μ λ λ°λμ§ μλ μμ ― or κ°
π const νΉμ§μ 보λ statelessWidgetκ³Ό statefulWidgetμ΄λ λΉμ·νλ€λ λλμ΄ λ€μ΄μ λ μ°κ΄μ±μ΄ μλ κΆκΈν΄μ‘λ€.
κ°λ const vs non-const Stateless vs Stateful κΈ°μ€ κ°μ΄ λ°λλκ°? UIκ° λ°λλκ°? κ³ μ λ κ² constβ μ λ μ λ°λStatelessWidgetβ UIκ° κ³ μ μ λμ μΈ κ² non-constβ μΈμ λ λ°λ μ μμStatefulWidgetβ setStateλ‘ UI λ³κ²½ κ°λ₯μ΅μ ν constλ μ¬μ¬μ© κ°λ₯, μ±λ₯ ν₯μStatelessλ μν μμ, μ¬λΉλλ κ°λ²Όμ
β
constμμ ―μ μ±λ₯μ μ 리(μ¬μ¬μ©λ¨)
βStatelessWidgetμμconstμμ±μ λ§μ΄ μ¬μ©
βStatefulWidgetλ μμ±μλconstμΌ μ μμ(μμ ― μ체λ λΆλ³, μνλ§ λ³ν¨)
π "λΆλ³μ±"μ΄λΌλ κ³΅ν΅ μ² νμ μμ§λ§, constλ λ©λͺ¨λ¦¬/μ±λ₯ μ΅μ ν, Statelessλ UI ν¨ν΄μ μ°¨μ΄λ€.
π λͺ¨λ UIλ₯Ό μμ ―μΌλ‘ ꡬμ±νκ³ , μνκ° λ°λ λλ§λ€ build ν¨μκ° νΈμΆλλ©° μμ ―μ΄ λ€μ κ·Έλ €μ§λ ꡬ쑰μ΄λ€.
π₯½ λκ°μ κ±Έ λ§€λ² μλ‘ λ§λ€λ©΄ μ±λ₯μ΄ λ¨μ΄μ§κΈ° λλ¬Έμ, μ¬μ¬μ© κ°λ₯ν μμ ―μ λ§λ€κ³ , ν¨μ¨μ μΌλ‘ κ΄λ¦¬νλ κ² μ€μνλ€.
β μ¬μ¬μ©μ μνλ μ½λ
const Text('Hello') // β constλκΉ μ¬μ¬μ©λ¨ (buildλ§λ€ μλ‘ μ λ§λ€μ΄λ λ¨)β μ»΄νμΌ νμμ λ©λͺ¨λ¦¬μ λ± ν λ² λ§λ€μ΄μ Έμ κ³μ μ
β μνκ° λ°λμ΄λ μ΄ μμ ―μ λ€μ λ§λ€μ§ μμ
β μ¬μ¬μ© μ λλ μ½λ
Text('Hello') // β const μ λΆμκΈ° λλ¬Έμ build λλ§λ€ μλ‘ μμ±λ¨β μΈνμ κ°μ 보μ¬λ λ§€λ² μ μΈμ€ν΄μ€ β λΉκ΅ λͺ» νκ³ λ€μ κ·Έλ¦Ό
π‘ μ¬μ¬μ© μ΅μ ν ν μ 리
νλͺ© μ€λͺ μμ β constμμ ― μ¬μ©λΆλ³ μμ ―μ 미리 λ§λ€μ΄ μ¬μ¬μ© const Text('νμ ')β μμ ― λΆλ¦¬ ν° μμ ―μ μͺΌκ°μ μν λ³κ²½ λ²μ μ΅μν MyButtonWidget()λ°λ‘ λΆλ¦¬β ListView.builder리μ€νΈ μμ ― μ¬μ¬μ© μ΅μ ν μλ μ§μ μ€ν¬λ‘€ κ°λ₯ν κΈ΄ 리μ€νΈ β keysνμ©μμ ― κ° λ³κ²½ μΆμ μ λͺ νν Key,ValueKeyλ±β const constructorμ μ컀μ€ν μμ ―λ μ¬μ¬μ© κ°λ₯νκ² const MyWidget()
β μ±λ₯ μ μ’μ μ
νλͺ© λ¬Έμ μμ β const μμ΄ λ°λ³΅ μμ ― μμ± λ§€λ² μλ‘ κ·Έλ €μ§ Text('λ°λ³΅')inforβ buildμ λ³μν μμ ― μν λ°λ λλ§λ€ μλ‘ μμ±λ¨ Text(DateTime.now())β StatelessμΈλ° setStateμ²λΌ μ¬μ© rebuildκ° μλ―Έ μμ StatelessWidgetμμμ λμ μ²λ¦¬
πΉ const constructor vs const μ¬μ©
| κ΅¬λΆ | π§± const constructor | π οΈ const μ¬μ© |
|---|---|---|
| μ μ μμΉ | ν΄λμ€ μ μλΆ (μμ±μμ λΆμ) | κ°μ²΄ μμ± μ (const MyWidget()) |
| μν | μ΄ ν΄λμ€λ const μΈμ€ν΄μ€ λ§λ€ μ μμ | μ΄ μΈμ€ν΄μ€λ₯Ό λΆλ³μΌλ‘ λ§λ€κ² λ€λ λ» |
| μ μ 쑰건 | λ΄λΆ νλλ λͺ¨λ finalμ΄μ΄μΌ ν¨ | μμ±μκ° constλ‘ μ μΈλΌ μμ΄μΌ ν¨ |
| μμ | const MyWidget({super.key}) | const MyWidget() |
πΉ const factory constructor
| νλͺ© | μ€λͺ |
|---|---|
| μλ―Έ | const + factory β μμ± μ΅μ ν + μΊμ±κΉμ§ ν¬ν¨ |
| λͺ©μ | κ°μ κ°μ΄λ©΄ κ°μ²΄ μ¬μ¬μ© (μ€λ³΅ μμ±μ λ§κ³ λ©λͺ¨λ¦¬ μ μ½) |
| λ΄λΆ ꡬν λ°©μ | Map λ±μ νμ©ν΄ μΊμ μ μ₯ |
| μμ | const ColorBox(0xFF0000) β λ΄λΆμμ μΊμλ κ°μ²΄ λ°ν |
πΉ const vs final μ°¨μ΄
| κ΅¬λΆ | final | const |
|---|---|---|
| μλ―Έ | ν λ²λ§ κ°μ μ νλ©΄ λ³κ²½ λΆκ° | μ²μλΆν° λ³νμ§ μλ μμ |
| π κ²°μ μμ | λ°νμ μ€ | μ»΄νμΌ νμ |
| π μ¬ν λΉ | β λΆκ° | β λΆκ° |
| μμ | final name = getName(); | const age = 20; |
| μμ ― μ | final String title; | const Text('κ³ μ ν
μ€νΈ') |
| βοΈ νΉμ§ | μΈλΆμμ μ£Όμ λ°μ λ μ μ© | μμ ― μ¬μ¬μ©κ³Ό μ΅μ νμ μ 리 |
πΈ Widget μ¬μ¬μ© μ΅μ ν ν
| β νλ©΄ μ’μ κ² | β νΌν΄μΌ ν κ² |
|---|---|
const μμ ― μ κ·Ή μ¬μ© | const μμ΄ λ§€λ² μ μμ ― λ§λ€κΈ° |
μμ ― λΆλ¦¬ (MyButtonWidget()) | 컀λ€λ build ν¨μμ λ€ λλ €λ£κΈ° |
ListView.builder μ¬μ© | 리μ€νΈ μ§μ λ°λ³΅λ¬ΈμΌλ‘ μμ± (for λ¬Έ λ±) |
keysλ‘ λ³κ²½ μΆμ κ΄λ¦¬ | key μμ΄ λμ 리μ€νΈ λ€λ£¨κΈ° |
β
const, final, μμ±μ ꡬ쑰 μ΄ν΄ π
β μμ ― μ¬μ¬μ© μ΅μ ν κ°λ π―
β Flutter λ¬Έλ²μ ν΅μ¬ μ€ μμ ― ꡬ쑰μ λ λλ§ μ±λ₯ νμ μλ£
1οΈβ£
Widget Lifecycle(μλͺ μ£ΌκΈ°)
StatefulWidgetμ΄ μΈμ initState,build,disposeλλμ§ μ΄ν΄νκΈ°
μ? β μν λ³νκ° λ§μ μ±μμ 리μμ€λ₯Ό ν¨μ¨μ μΌλ‘ λ€λ£¨λ €λ©΄ κΌ νμνλ€.
μΆμ² ν€μλ: initState(), didUpdateWidget(), dispose()
2οΈβ£
Stateκ΄λ¦¬ κΈ°μ΄
setStateλ‘ κ΄λ¦¬νλ μνλ₯Ό μ‘°κΈ λ 체κ³μ μΌλ‘ λ€λ£¨λ λ²
setState()μ΄ν΄
λΆλͺ¨-μμ μμ ― κ° λ°μ΄ν° μ λ¬(props,callback)
μ΄ν:
Provider,Riverpod,Blocκ°μ κ³ κΈ μνκ΄λ¦¬λ‘ μ΄μ΄κ°κΈ°
3οΈβ£ λ μ΄μμ λ§μ€ν°νκΈ°
Expanded,Flexible,Spacer,Align,Stack,Positionedκ°μ μμ ―
λ μ΄μμμ΄ λ§κ°μ§λ μ΄μ λ₯Ό μκ² λκ³ , βUIβ λ§λ€κΈ° μν λ μ΄μμ μ€κ³ κ°κ° ν€μ°κΈ°.
4οΈβ£
Navigator&Routing(νμ΄μ§ μ ν)
μ¬λ¬ νλ©΄μ μ΄λνκ³ , λ€λ‘κ°κΈ°, μΈμ μ λ¬ λ±
Navigator1.0 vs 2.0 μ°¨μ΄
push,pop,pushReplacement,popUntil
Routeμ λ°μ΄ν° μ λ¬νλ λ²
5οΈβ£ μ€μ μ± νλ‘μ νΈ ν΄λ³΄κΈ°
μ§κΈκΉμ§ λ°°μ΄ κ²λ€μ ν λ² μ¨λ³΄λ©΄μ ν΅ν© 볡μ΅
μ± μμ΄λμ΄:
TODO μ±
κ°λ¨ν νμ΄λ¨Έ μ±
κ°λ¨ν λ΄μ€ λ·°μ΄ or λ μ¨ μ±
π» λ§₯ νκ²½μμλ λ€λ₯Έ μ€λ₯κ° λ°μνκΈ°λ νκ³ , κΈ°μ‘΄ μλμ° νκ²½λ§μΌλ‘λ νΈνμ± λ¬Έμ κ° μκΈ° λλ¬Έμ μ°μ λ§₯λΆμ λ³ννλ©° νμ΅νλκ² μ’μ κ² κ°λ€.
κΈ°κΈ° μ μ²μ ν΄μ λ¬Έμ κ° μμΌλ©΄, λ€μμ£Ό μ€μ μλ Ήν΄μ λ§₯ κ°λ° νκ²½ μΈν μ ν΄μΌλ κ² κ°λ€.
π± μ€λμ 곡λΆλ λμ΄ μμλ κ² κ°λ€..
constλ₯Ό μ§μ°λ©΄ μ μ€λ₯λλμ§ κΆκΈ
> stateless statfulμ΄λ λΉμ·νκ±° κ°μ
> κ·Όλ° const constructorλ λμ§λ κΆκΈ
> factory factory constructorλ μλ€κ³ ν¨
> constλ final μ°¨μ΄κ° λμ§ μκ³ μΆμ
> ....
μ΄λ° μμΌλ‘ νΈκΈ°μ¬κ³Ό.. κΆκΈμ¦μ΄ κ°λν 무νμ κ΅΄λ μ λΉ μ Έ μ μ λ€λ₯Έ μμ ― 곡λΆλ λͺ»νλ κ² κ°λ€. κΆκΈμ¦μ΄ ν΄μλμ΄μ μ’κΈ΄νλ° λ΄μ©μ΄ λ§μμ μλ²½νκ² κΈ°μ΅νκ±°λ λ μ¬λ¦¬μ§λ λͺ»ν κ² κ°μ§λ§, μ°μ μ΄ν΄λ μ΄λμ λ λμ΄μ λ§μ‘±μ€λ½λ€.