-
android studio์์ flutter project๋ฅผ ์ฒ์ ๋ง๋ค์์ ๋ ๋ณด์ด๋ ๊ธฐ๋ณธ ์ฑ์ ์ฝ๋ ๋ถ์.
์ ์ฒด ์ฝ๋
//main.dart import 'package:flutter/material.dart'; //์ฑ ์์ ๋ถ๋ถ void main() { runApp(MyApp()); } //์์ ํด๋์ค. ๋จธํฐ๋ฆฌ์ผ ๋์์ธ ์ฑ ์์ฑ class MyApp extends StatelessWidget { // This widget is the root of your application. @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Demo', theme: ThemeData( // This is the theme of your application. // // Try running your application with "flutter run". You'll see the // application has a blue toolbar. Then, without quitting the app, try // changing the primarySwatch below to Colors.green and then invoke // "hot reload" (press "r" in the console where you ran "flutter run", // or simply save your changes to "hot reload" in a Flutter IDE). // Notice that the counter didn't reset back to zero; the application // is not restarted. primarySwatch: Colors.blue, // This makes the visual density adapt to the platform that you run // the app on. For desktop platforms, the controls will be smaller and // closer together (more dense) than on mobile platforms. visualDensity: VisualDensity.adaptivePlatformDensity, ), home: MyHomePage(title: 'Flutter Demo Home Page'), //ํ์ํ ํ๋ฉด์ ์ธ์คํด์ค ); } } //์์ ํด๋์ค๊ฐ ์ค์ ๋ก ํ์ํ๋ ํด๋์ค. ์นด์ดํฐ ์ฑ ํ๋ฉด class MyHomePage extends StatefulWidget { MyHomePage({Key key, this.title}) : super(key: key); // This widget is the home page of your application. It is stateful, meaning // that it has a State object (defined below) that contains fields that affect // how it looks. // This class is the configuration for the state. It holds the values (in this // case the title) provided by the parent (in this case the App widget) and // used by the build method of the State. Fields in a Widget subclass are // always marked "final". final String title; @override _MyHomePageState createState() => _MyHomePageState(); } //์ ํด๋์ค์ ์ํ๋ฅผ ๋ํ๋ด๋ state ํด๋์ค class _MyHomePageState extends State<MyHomePage> { int _counter = 0; //ํ๋ฉด์ ํ์ํ ์ํ๊ฐ. ์นด์ดํฐ ์ซ์ //์นด์ดํฐ ๋ณ์๋ฅผ 1 ์ฆ๊ฐ์ํค๊ณ ํ๋ฉด์ ๋ค์ ๊ทธ๋ฆฌ๋ ๋ฉ์๋ void _incrementCounter() { setState(() { //ํ๋ฉด์ ๋ค์ ๊ทธ๋ฆฌ๋๋ก ํ๋ ํจ์. statefulWidget๋ง ๊ฐ๋ฅ? // This call to setState tells the Flutter framework that something has // changed in this State, which causes it to rerun the build method below // so that the display can reflect the updated values. If we changed // _counter without calling setState(), then the build method would not be // called again, and so nothing would appear to happen. _counter++; }); } //ํ๋ฉด์ UI๋ฅผ ๊ทธ๋ฆฌ๋ ๋ฉ์๋. ๊ทธ๋ ค์ง ์์ ฏ์ ๋ฐํ @override Widget build(BuildContext context) { // This method is rerun every time setState is called, for instance as done // by the _incrementCounter method above. // // The Flutter framework has been optimized to make rerunning build methods // fast, so that you can just rebuild anything that needs updating rather // than having to individually change instances of widgets. return Scaffold( //๋จธํฐ๋ฆฌ์ผ ๋์์ธ ๊ธฐ๋ณธ ๋ผ๋ ์์ ฏ appBar: AppBar( //์๋จ ์ฑ๋ฐ // Here we take the value from the MyHomePage object that was created by // the App.build method, and use it to set our appbar title. title: Text(widget.title), ), body: Center( //ํ์ํ ๋ด์ฉ // Center is a layout widget. It takes a single child and positions it // in the middle of the parent. child: Column( // Column is also a layout widget. It takes a list of children and // arranges them vertically. By default, it sizes itself to fit its // children horizontally, and tries to be as tall as its parent. // // Invoke "debug painting" (press "p" in the console, choose the // "Toggle Debug Paint" action from the Flutter Inspector in Android // Studio, or the "Toggle Debug Paint" command in Visual Studio Code) // to see the wireframe for each widget. // // Column has various properties to control how it sizes itself and // how it positions its children. Here we use mainAxisAlignment to // center the children vertically; the main axis here is the vertical // axis because Columns are vertical (the cross axis would be // horizontal). mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ Text( 'You have pushed the button this many times:', ), Text( '$_counter', //๋ณ์๋ฅผ ํ์ style: Theme.of(context).textTheme.headline4, ), ], ), ), floatingActionButton: FloatingActionButton( onPressed: _incrementCounter, //ํด๋ฆญ์ ์ ๋ฉ์๋ ์คํ tooltip: 'Increment', child: Icon(Icons.add), //์๋จ ์ฑ๋ฐ ), // This trailing comma makes auto-formatting nicer for build methods. ); } }
์ ์ฒด ์ฝ๋๋ฅผ ๋ฉ์ด๋ฆฌ๋ก ํ์ ํด๋ณด๋ฉด ์๋์ ๊ฐ๋ค.
import 'package:flutter/material.dart'; void main() {} class MyApp extends StatelessWidget {} class MyHomePage extends StatefulWidget {} class _MyHomePageState extends State<MyHomePage> {}
์์ ์ธ ๋ฉ์ด๋ฆฌ๋ ์ฌ์ค์ ์์ ํ์ง ์๋ ๋ถ๋ถ. ์ฃผ์ ์ฝ๋๋ ์๋ ๋ ๋ฉ์ด๋ฆฌ์ ์๊ณ , ์ํ ์ฑ์ ํ๋ฉด์ ๋ํ๋ด๋ ์ฝ๋๋ค์. ์ฌ์ค์ ๋ง์ง๋ง ๋ฉ์ด๋ฆฌ์ ๋ชจ๋ ์ฝ๋๋ฅผ ์์ฑ.
์ด์ ๋ถํฐ ํ ์ค์ฉ ์ดํด๋ณด๊ฒ ์.
import 'package:flutter/material.dart';
flutter์์๋ ํ๋ฉด์ ๊ทธ๋ฆฌ๋ ๋ชจ๋ ๋์์ธ ์์๋ฅผ widget์ด๋ผ๊ณ ํจ.
importํ๋ 'package:flutter/material.dart' ํจํค์ง์๋ ๋จธํฐ๋ฆฌ์ผ ๋์์ธ ์์ ๋ค์ด ํฌํจ๋์ด ์์.
๋จธํฐ๋ฆฌ์ผ ๋์์ธ : ํ๋ซ ๋์์ธ์ ์ฅ์ ์ ์ด๋ฆฌ๋ฉด์๋ ๋น์ ๋ฐ๋ฅธ ์ข ์ด์ ๊ทธ๋ฆผ์ ํจ๊ณผ๋ฅผ ์ด์ฉํ์ฌ ์ ์ฒด๊ฐ์ ์ด๋ฆฌ๋ ๋์์ธ ๋ฐฉ์์ ๋งํ๋ค. 2014๋ ๊ตฌ๊ธ์ด ์๋๋ก์ด๋ ์ค๋งํธํฐ์ ์ ์ฉํ๋ฉด์ ๋๋ฆฌ ํผ์ง๊ธฐ ์์ํ๋ค
void main() => runApp(MyApp());
main() ์ ์ฑ์ ์์์ . runApp()์ ์ธ์๋ก MyApp()์ ์ ๋ฌํ๋ค.
class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp(...์๋ต...); } }
StatelessWidget ํด๋์ค. ์ํ๊ฐ ์๋ ์์ ฏ์ ์ ์ํ๋๋ฐ ์ฌ์ฉ. => ํ ๋ฒ๋ง ๊ทธ๋ ค์ง๋ค! (๋ค์ ๊ทธ๋ ค์ง์ง ์์)
์ด๋ฐ ํด๋์ค๋ property๋ก ๋ณ์๋ฅผ ๊ฐ์ง์ง ์์. (๋ค์ ๊ทธ๋ ค์ง์ง ์์ผ๋๊น)
MyApp ํด๋์ค๋ StatelessWidget ํด๋์ค์ ์๋ธํด๋์ค.
์ด MyApp()์ runApp()์ ์ ๋ฌ๋๋ค.
StatelessWidget๋ build() ๋ฉ์๋๋ฅผ ๊ฐ์ง๋๋ฐ, ์ด ๋ฉ์๋๋ ์์ ฏ์ ์์ฑํ ๋ ํธ์ถ๋์ด ์ค์ ๋ก ํ๋ฉด์ ๊ทธ๋ฆด ์์ ฏ์ ๋ฐํ.
์ฆ, MyApp์ด build๊ฐ ๋ฆฌํดํ๋ MaterialApp() ๊ฐ์ฒด๋ฅผ ๋ฐํํ๋ค.
Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Demo', theme: ThemeData( primarySwatch: Colors.blue, visualDensity: VisualDensity.adaptivePlatformDensity, ), home: MyHomePage(title: 'Flutter Demo Home Page'), ); }
build๊ฐ ๋ฐํํ๋ MaterialApp class. ์ฌ๊ธฐ๊น์ง๋ ๊ฑฐ์ ๋ชจ๋ ํ๋ก์ ํธ๊ฐ ๋์ผํจ.
title, theme, home ์ธ๊ฐ์ง ์ด๋ฆ ์๋ ์ธ์๋ฅผ ์ค์ ํด ์์ ฏ์ ์์ฑ์ ํํ.
title : ์ ๋ชฉ
theme : ํ ๋ง. ์ฌ๊ธฐ์๋ blueํ ๋ง.
home : ์ฌ๊ธฐ์ ์์ฑํ๋ ์์ ฏ์ด ์ค์ ์ด ์ฑ์ด ํ์ํ๋ ์์ ฏ์ด ๋จ.
class MyHomePage extends StatefulWidget { MyHomePage({Key key, this.title}) : super(key: key); final String title; @override _MyHomePageState createState() => _MyHomePageState(); }
์์ home ์ธ์์ ๋ค์ด๊ฐ๋ MyHomePage class.
์ํ๊ฐ ์๋ ์์ ฏ์ ์ ์ํ ๋๋ StatefulWidget class๋ฅผ ์ฌ์ฉ.
MyHomePage class์ ์์ฑ์๋ key, title์ ์ต์ ์ผ๋ก ๋ฐ์์ super๋ฅผ ์ด์ฉํด ๋ถ๋ชจ ํด๋์ค์ ์์ฑ์์ key๋ฅผ ์ ๋ฌ.
MyHomePage class๋ ์์๋ฐ์ createState()๋ฅผ ์ฌ์ ์ํด์ _MyHomePageState class์ ์ธ์คํด์ค๋ฅผ ๋ฐํ. ์ด ๋ฉ์๋๋ StatefulWidget์ด ์์ฑ๋ ๋ ํ๋ฒ๋ง ์คํ๋จ.
class _MyHomePageState extends State<MyHomePage> { int _counter = 0; //ํ๋ฉด์ ํ์ํ ์ํ๊ฐ. ์นด์ดํฐ ์ซ์ ...์๋ต... //ํ๋ฉด์ UI๋ฅผ ๊ทธ๋ฆฌ๋ ๋ฉ์๋. ๊ทธ๋ ค์ง ์์ ฏ์ ๋ฐํ @override Widget build(BuildContext context) { return Scaffold(...์๋ต...); } }
์ํ ํด๋์ค : State class๋ฅผ ์์๋ฐ์ ํด๋์ค. ์ํ ํด๋์ค๋ ๋ณ๊ฒฝ ๊ฐ๋ฅํ ์ํ๋ฅผ ํ๋กํผํฐ ๋ณ์๋ก ํํ.
Widget build๋ _MyHomePageState ํด๋์ค์ ์ํ์ ๋ฐ๋ผ ํ๋ฉด์ ๊ทธ๋ ค์ง ์ฝ๋๋ฅผ ์์ฑ. ๋ชจ์์ ์๊น build์ ๋์ผ.
์์ ฏ์์ ์์ ฏ์ผ๋ก ๊ฐ ์ ๋ฌ?
์์ฑ์๋ฅผ ์ด์ฉ. (ex/ MyHomePage({Key key, this.title}) : super(key: key)'
์ํ ํด๋์ค์์ StatefulWidget ์ ์ ๊ทผํ๋ ค๋ฉด widget property๋ฅผ ์ฌ์ฉ. (ex/ title:Text(widget.title))state ํด๋์ค์์๋ ์ฃผ๋ก ์ํ๋ฅผ ์ ์ฅํ ๋ณ์๋ค, ๊ทธ ๋ณ์๋ฅผ ์กฐ์ํ ๋ฉ์๋๋ฅผ ์์ฑ.
์ ์์ ์ State class๋ ๋ค์๊ณผ ๊ฐ๋ค.
class _MyHomePageState extends State<MyHomePage> { int _counter = 0; //ํ๋ฉด์ ํ์ํ ์ํ๊ฐ. ์นด์ดํฐ ์ซ์ void _incrementCounter() { setState(() { _counter++; }); } @override Widget build(BuildContext context) { return Scaffold(...์๋ต...); } }
์ ์ํ _counter๋ 0์ผ๋ก ์ด๊ธฐํ.
_incrementCounter() method๋ setState()๋ฅผ ์คํ. setState์ ์ธ์๋ _counter++์ธ ์ต๋ช ํจ์.
setState() : ํ๋ฉด์ ๋ค์ ๊ทธ๋ฆฌ๋ ์ญํ ! => build()๋ฅผ ๋ค์ ์คํ ํ๋ค. (State class๊ฐ ์ ๊ณตํ๋ ๋ฉ์๋)
์ฆ, MyHomePage๋ StatefulWidget์ ์๋ธ ํด๋์ค์ด๋ฉฐ, ์ํ๋ฅผ ๊ฐ์ง ์ ์์.
์ํ๋ State ํด๋์ค์ ์๋ธ ํด๋์ค๋ก ์ ์. (๋ณ๊ฒฝ ๊ฐ๋ฅํ ์ํ๋ _counter)
์ด์ _MyHomePage์ build๊ฐ ํธ์ถ๋ ๋ ๋ถ๋ฆฌ๋ Scaffold class๋ฅผ ์ดํด๋ณด์.
Scaffold class๋ ๋จธํฐ๋ฆฌ์ผ ๋์์ธ ์ฑ์ ๋ผ๋๊ฐ ๋๋ ์์ ฏ. MaterialApp -> Scaffold๊ฐ ๊ธฐ๋ณธ ํํ.
์ฝ๊ฒ ๋งํ๋ฉด material design์ ๋๋ต์ ์ธ ์์น? ๋ฅผ ์ง์ ํด ๋๋ Widget.
origogi.github.io/flutter/Scafold/
Scaffold( appBar: AppBar( //์๋จ ์ฑ๋ฐ title: Text(widget.title), ), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ Text( 'You have pushed the button this many times:', ), Text( '$_counter', //๋ณ์๋ฅผ ํ์ style: Theme.of(context).textTheme.headline4, ), ], ), ), floatingActionButton: FloatingActionButton( onPressed: _incrementCounter, //ํด๋ฆญ์ ์ ๋ฉ์๋ ์คํ tooltip: 'Increment', child: Icon(Icons.add), //์๋จ ์ฑ๋ฐ ), );
์ด ์์ ์์๋ ์ธ์๋ก appBar, body, floatingActionButtion์ ์ ์.
appBar
์ฌ๊ธฐ์ AppBar class์ ๊ฐ์ฒด ์ ๋ฌ. ์๋จ์ ์ ๋ชฉ, ๋ฉ๋ด๋ฅผ ํ์ํ๋ ์์ญ.
AppBar class๋ title์ Text widget์ ์ ์. Text widget์ ๊ธ์๋ฅผ ๋ํ๋ด๋ ์์ ฏ์ด๋ฉฐ ์ธ์๋ก widget.title๋ฅผ ๋ฐ์. widget์
StatefulWidget class (MyHomePage)์ ํ๋กํผํฐ๋ฅผ ์ฐธ์กฐํ ๋ ์ฌ์ฉ.
body
_counter๋ ์ ์ํ ๋ณ์๋ผ Text ์์ ฏ์ ํ์ํ๋ ค๋ฉด ๋ฌธ์์ด๋ก ๋ณ๊ฒฝํด์ผ ํจ. ๊ทธ๋์ ๋ณ์์ ๊ฐ์ ๋ฌธ์์ด ํํ๋ก ๋ณ๊ฒฝํ๊ณ ์ ํ ๋ ๋ณ์ ์์ $๋ฅผ ๋ถ์.
floatingActionButtion
์ฌ์ฉ์๊ฐ +๋ฒํผ์ ๋๋ฅด๋ฉด ๋ค์๊ณผ ๊ฐ์ _increamentCounter() ๋ฉ์๋๊ฐ ํธ์ถ๋จ.
ํธ์ถ๋๋ฉด setState()์ ์ํด _counter++๋ฅผ ํ ๋ค, build๊ฐ ๋ค์ ํธ์ถ => ํ๋ฉด์ด ๋ค์ ๊ทธ๋ ค์ง
onPressed : ๋ฒํผ์ด ๋๋ฌ์ง๋ฉด ์คํ๋๋ ๋ถ๋ถ. ์ฌ๊ธฐ์ ๋์์ํฌ ์ฝ๋๋ฅผ ํจ์ ํํ๋ก ์์ฑ. Dart์์๋ ํจ์๋ ๊ฐ์ผ๋ก ์ฌ์ฉ ๊ฐ๋ฅ!
tooltip : ์ฌ์ฉ์๊ฐ +๋ฅผ ๊ธธ๊ฒ ํฐ์งํ ๋ ํ์ํ ๊ธ์๋ฅผ ์ง์ .
child : ์์ด์ฝ instance๋ฅผ ์ ์ํด์ +๋ชจ์ ๋ฒํผ์ ํํ.
์ฐธ์กฐ : ์ค์ค์์ ํ๋ฌํฐ ์์กด์ฝ๋ฉ'๐STUDY > ๐ซDart&Flutter' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[flutter] widget 2 : ํ๋ฉด ๋ฐฐ์น๋ฅผ ์ํ ๋ ์ด์์-2 (0) 2021.02.07 [flutter] widget 1 : ํ๋ฉด ๋ฐฐ์น๋ฅผ ์ํ ๋ ์ด์์ (0) 2021.02.07 [flutter] StatelessWidget / StatefulWidget ์ค์ต (0) 2021.02.06 [flutter] android studio flutter Widget ์๋์์ฑ (0) 2021.02.06 [์ธ์ด] Dart ๋ฌธ๋ฒ ์ ๋ฆฌ (2) 2021.01.27 ๋๊ธ