String
void main() {
print('Hello World');
print("Hello World");
}
작은 따옴표, 큰 따옴표 모두 가능
변수
void main() {
var a = 10;
var str = 'Hello';
var b = 3.5;
var isMarried = true;
}
Dart에서는 타입을 추론하기 때문에 var로 통일 가능
dynamic
void main() {
dynamic c = 10;
myPrint(10);
}
myPrint(dynamic str) {
}
일반적인 변수를 사용하는 경우 var
dynamic은 다른 함수와 같이 사용할 때
Java의 Object 같은 느낌
num
void main() {
int n = 10;
// double d = n; // Java는 자동으로 type casting 되어 컴파일에 이상이 없다.
// Flutter는 무조건 type casting 해 줘야 함
num d = n; // type을 num으로 해 주면 int, double 상관없이 사용가능
}
myPrint(num str) {
}
num은 int와 double을 포함한다.
JSON 데이터를 통해서 온도에 대한 값을 읽어왔는데 어떨 때는 18, 어떨 때는 18.5일 때 둘 다 받아오려면 num 사용해야 한다.
final
void main() {
final e = 10;
}
Java와 동일하지만 type을 쓰지 않아도 된다.
한 번 초기화되면 변경할 수 없는 값
const
void main() {
final a = 10;
const b = 20;
}
const와 final은 모두 값 변경이 불가능하다.
const는 컴파일 타임의 상태, 즉 메모리에 이미 저장이 되어 버린 것
final은 동적으로 메모리에 할당됨
const는 재사용을 많이 해야하는 케이스(Padding 등)에 유용하다.
Collection
void main() {
List<String> items = ['a', 'b', 'c'];
var items = [1, 2, 3];
print(items);
// List에 접근하는 방법은 Java에서 배열에 접근하는 방법과 동일하다. (Dart에는 배열이 없음)
print(items[0]);
}
Set
void main() {
var items = [1, 2, 3]; // 배열 형태로 사용하면 List
var itemSet = {1, 2, 3};
print(itemSet);
}
Map
void main() {
var itemMap = {
'key1': 1,
'key2': 2,
'key3': 3,
};
print(itemMap);
}
JSON 형태로 만들면 Map
spread 연산자(...)
void main() {
var itmes = [1, 2, 3];
var items2 = [...items, 4, 5];
print(items2); // [1, 2, 3, 4, 5]
}
메소드
void main() {
thing('홍길동');
something('홍길동', age: 20);
}
void thing(String name, {int age = 10}) { // {option = default}
}
void something(String name, {@required int age}) {
}
메소드는 Dart에서 1급 객체(parameter로 전달할 수 있는 객체)
class MainPage extends StateefulWidget {
@override
_MainPageState createState() => _MainPageState();
}
class _MainPageState extends State<MainPage> {
void something() {
}
@override
Widget build(BuildContext context) {
return Container(
child: RaisedButton(onPressed: something, // 이름만 써도 됨(1급 객체 취급)
) // RaisedButton
); // Container
}
}
type 비교(is, is not)
void main() {
var a = 10;
if (a is int) {
print('정수');
}
if (a is! int) {
print('정수가 아님');
} else {
print('정수');
}
}
type cast
void main() {
var a = 10;
var b = 3.5;
b = a as double;
}
??
void main() {
String name;
print(name); // null
// null일 때 기본값을 주고 싶으면
print(name ?? '널');
// name이 null이 아닐 때만 실행
print(name?.toLowerCase());
}
Class
void main() {
var person = Person('홍길동', age: 10); // new 키워드 생략 가능
}
class Person {
String name;
int age;
Person(this.name, {this.age}); // Constructor
}
void main() {
var person = Person('홍길동');
print(person.name); // 제 이름은 홍길동
}
class Person {
String _name; // private
int _age;
String get name => '제 이름은 $_name'; // 람다식
}
void main() {
var person = Person();
person.setName('홍길동');
person.setAge(10);
var person2 = Person()
..setName('홍길동')
..setAge(10);
}
class Person {
String name;
int age;
void setName(String name) {
this.name = name;
}
void setAge(int age) {
this.age = age;
}
}
class Employee implements Person { // interface처럼 사용 가능함
// 다 override 강제로 해야 함
}
class Person {
String name;
int age;
void setName(String name) {
this.name = name;
}
void setAge(int age) {
this.age = age;
}
}
implements를 사용하면 override 강제로 해야 함
class Employee with Person {
@override
void setName(String name) {
}
}
class Person {
String name;
int age;
void setName(String name) {
this.name = name;
}
void setAge(int age) {
this.age = age;
}
}
선택적으로 override 하고 싶을 때 with를 사용하면 된다. (Dart의 mixin 기능)
Future
클릭을 했는데 이 안에서 네트워크 요청을 해야 하면 그 요청은 비동기로 실행될 것이고, 언제 끝나는지는 모른다.
그런 메소드들은 모두 future 형태
void main() {
print('시작');
networkRequest(); // 비동기로 요청
print('끝');
}
Future<void> networkRequest() async {
print('네트워크 요청 시작');
await Future.delayed(Duration(seconds: 3));
print('네트워크 요청 끝'); // 3초 후에 나오게 된다.
return; // 생략 가능
}
StreamBuilder
setState는 전체를 다시 build 한다. 중간에 로직이 껴 있을 때 쓸데없이 호출되는 경우가 있음.
import 'dart:async';
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
void _incrementCounter() {
setState(() {
_counter++;
});
}
@override
Widget build(BuildContext context) {
return 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.display1,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
),
);
}
}
StreamBuilder를 이용하면 해당 부분만 다시 그려진다. 성능 등 여러가지 면에서 좋다.
import 'dart:async';
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
var _counterController = StreamController<int>()..add(0);
void _incrementCounter() {
_counter++;
_counterController.add(_counter);
}
@override
Widget build(BuildContext context) {
return 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:',
),
StreamBuilder<int>(
stream: _counterController.stream,
builder: (context, snapshot) {
return Text(
'${snapshot.data}',
style: Theme.of(context).textTheme.display1,
);
}
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
),
);
}
}
주석
/// : 정보가 보인다. 클래스나 메소드 문서화를 하고 싶을 때 사용
'Flutter' 카테고리의 다른 글
[Mac] Flutter 설치 (0) | 2019.12.18 |
---|