반응형

Everything is a Widget.

플러터는 화면에 그려지는 모든 요소가 위젯으로 구성되어 있다.

자주 사용하는 위젯으로 텍스트, 제스처, 디자인. 배치 관련 위젯 등이 있다.

위젯은 현재 주어진 state 를 기반으로 어떤 UI 를 구현할지 정의한다.

state 가 변경되면 기존 위젯의 state 와 새로운 위젯의 state 를 비교하여 UI 변화를 반영할때 최소한 변경 사항을 산출하여 화면을 그려낸다.

자식(child)를 하나만 갖는 위젯

 - Container 위젯 : 자식을 담는 컨테이너 역할. 배경색, 너비와 높이, 테두리등의 디자인을 지정.

 - GestureDetector 위젯 : 제스처 기능을 자식 위젯에서 인식하는 위젯. 탭, 드래그, 더블클릭 등 제스처 기능이 자식 위젯에서 인식되었을 때 함수 실행.

 - SizeBox 위젯 : 높이와 너비를 지정하는 위젯. Container 위젯과 다르게 디자인적인 요소는 적용할 수 없고 const 생성자로 선언할 수 있어서 퍼포먼스 측면에서 더 효율적이다.

 

다수의 자식(child)를 입력 할 수 있는 위젯

 - Column 위젯 : children 매개변수에 입력된 모든 위젯들을 세로로 배치.

 -Row 위젯 :  children 매개변수에 입력된 모든 위젯들을 가로로 배치.

 - ListView 위젯 : 리스트를 구현할 때 사용. children 매개변수에 다수의 위젯을 입력할 수 있으며 입력된 위젯이 화면을 벗어나게되면 스크롤이 가능해진다.

반응형
반응형

이제 드디어 코딩해볼 시간!!

가장 기본인 Hello World 를 출력해보자!!

 

플러터 프로젝트를 생성하면 [프로젝트 폴더]/llib/main.dart 파일이 생긴다.

파일의 내용을 전부 지운 후 아래 코드를 입력.

// 머터리얼 디자인 import
// 기본 위젯 제공
import 'package:flutter/material.dart';

// 플러터 프로젝트 실행하는 함수
void main() {
  runApp(
  	// 머터리얼 디자인 위젯
  	MaterialApp(
    	// Scaffold 위젯
    	home: Scaffold(
        	// Text 위젯
        	body: Text(
            	'Hello World',    // 마지막 매개변수 끝에 콤마
            ),
         ),
     ),
  );
}

MaterialApp : 머터리얼 디자인 기반의 위젯을 사용

Scaffold 위젯 : 화면 전체를 차지. 레이아웃을 도와주고 UI 관련 특수 기능 제공(알림과 같은 스낵바 실행, 화면의 위에 앱바를 추가, 아래에 탭바를 추가 등)

※ MaterialApp 과 Scaffold 위젯을 추가하는 것이 기본 설정.

Text 위젯 : 글자를 화면에 출력하기 위해 사용.

 

실행

에뮬레이터를 선택하고 실행 버튼을 클릭한다.

 

에뮬레이터에서 결과 화면 확인.

- 화면 좌측 상단에 Hello World 글자가 보인다.(자세히 봐야 보인다. --;;)

기본 실행 완료!!

 

반응형
반응형

실제 기기 없이 에뮬레이터에서 테스트 하기 위한 방법!!

 

1. 안드로이드 에뮬레이트 생성

안드로이드 스튜디오에서 AVD Manager 버튼을 클릭.

 

좌측 하단의 Create Virtual Device... 버튼을 클릭

 

Category 에서 Phone 선택 후 Pixel 2 를 선택. Next 버튼 클릭.

 

OS는 API 33 을 선택!! Download 하면 된다. Next 버튼 클릭.

 

에뮬레이터 이름을 설정하고.. 좌측 하단의 Show Advanced Settings 버튼 클릭.

 

Internal Storage 를 넉넉하게 8GB 로 설정. Finish 클릭하여 완료한다.

 

에뮬레이터가 추가 된 것을 확인 할 수 있다.(기존에 API 30 은 삭제했다)

 

2. iOS 심뮬레이터는 Mac OS 환경에서 가능하므로... 패스... --;;

 

 

반응형
반응형

이제 직접 코딩하면서 배워보자!!

그동안 손이 근질근질.. 눈꺼풀이 천근만근이었을 것이다!!

 

1. 안드로이드 스튜디오에서 플러터 프로젝트 생성(GUI)

File > New > New Flutter Project...

 

Flutter Application 선택

 

Application 설정.

 - 소스 위치 : [플러터 프로젝트 디렉토리]\[플러터 프로젝트 명]

 - 플러터 SDK 설치 Path 설정

 

마지막으로 패키지 명을 입력 후 Finish

 

2. CLI 로 프로젝트 생성

$ flutter create hello_world2

....

All done!
You can find general documentation for Flutter at: https://docs.flutter.dev/
Detailed API documentation is available at: https://api.flutter.dev/
If you prefer video documentation, consider: https://www.youtube.com/c/flutterdev

In order to run your application, type:

  $ cd hello_world2
  $ flutter run

Your application code is in hello_world2\lib\main.dart.

 

안드로이드 스튜디오에서 가져오기

 - CLI 로 생성한 hello_world2 디렉토리 Open

 

안드로이드 스튜디오에서 프로젝트 확인

 - hello_world\lib\main.dart 파일이 메인

 

반응형
반응형

Flutter는 고성능, 고품질의 iOS, Android, 웹(tech preview) 앱을 단일 코드 베이스로 개발할 수 있는 모바일 앱 SDK입니다.

 

스크롤 동작, 글씨, 아이콘과 같이 플랫폼 별로 달라지는 부분들을 아울러서 서로 다른 플랫폼에서도 자연스럽게 동작하는 고성능의 앱을 개발할 수 있게 하는 것이 Flutter의 목표입니다.

 

Flutter의 장점
● 높은 생산성
    ○ 단일 코드베이스로 iOS와 Android 개발할 수 있습니다.
    ○ 모던하고 표현적인 언어 그리고 선언적 접근법을 통해 단일 OS에서 더 적은 코드로 더 많은 것을 할 수 있습니다.
     쉽게 프로토타입을 제작하고 반복할 수 있습니다.
        √ 앱 실행 중에 코드를 바꾸고 리로드하여 개발을 할 수 있습니다. ( hot reload)
        √ 앱이 중단된 지점에서 문제를 수정하고 디버깅을 이어나갈 수 있습니다.

 아름답고, 고도로 커스터마이징된 UX를 만들 수 있습니다.
     Flutter의 자체 프레임워크를 사용하여 머티리얼 디자인과 쿠퍼티노 (iOS) 스타일의 풍부한 위젯들을 만들 수 있습니다.
     OEM 위젯의 제한없이 맞춤형의 아름다운 브랜드 주도 디자인을 실현할 수 있습니다.

 

핵심 원리

Flutter는 현대적인 react-style 프레임워크, 2D 렌더링 엔진, 바로 이용 가능한 위젯들, 그리고 개발 툴들을 포함합니다.

이러한 구성 요소들을 통해 앱을 디자인, 개발, 테스트 그리고 디버깅할 수 있습니다. 모든 것은 몇가지 핵심 원리들을 중심으로 구성됩니다.

 

모든 것은 위젯입니다

위젯은 Flutter 앱 UI의 기본 단위입니다. 모든 위젯은 UI의 불변 선언입니다. 

뷰, 뷰 컨트롤러, 레이아웃 그리고 기타 다른 속성들을 분리하는 다른 프레임워크들과 다르게, Flutter는 일관적이고 통일된 오브젝트 모델을 갖고 있는데, 그것이 바로 위젯입니다.

 

 

위젯은 다음의 것들을 정의할 수 있습니다:

● 구조적인 요소 (예: 버튼이나 메뉴)

● 스타일적인 요소 (예: 폰트나 색상)

● 레이아웃 요소 (예: 패딩)

● 기타 등등…

위젯은 구성을 기반으로 계층 구조를 형성합니다. 

각 위젯은 내부에 중첩되고 부모의 속성들을 상속받습니다.

별도 “application” 오브젝트가 없는 대신 최상위 위젯이 그 역할을 하게 됩니다.

 

프레임워크에게 위젯을 계층 구조 상 다른 위젯으로 교체하게 함으로써, 사용자 상호작용과 같은 이벤트를 구현할 수 있습니다. 프레임워크는 새로운 위젯과 기존 위젯을 비교하고 효을적으로 UI를 업데이트하게 됩니다.

 

구성 > 상속

위젯은 종종 강력한 효과를 내기 위해 단일 목적의 여러 작은 위젯들로 구성됩니다. 

예를 들어, 일반적으로 사용되는 Container 위젯은 painting, positioning, sizing과 같은 레이아웃 관련 위젯들로 구성됩니다. 

좀더 구체적으로 Container는 LimitedBox, ConstrainedBox, Align, Padding, DecoratedBox, Transform 위젯들로 구성됩니다. 

커스터마이징을 위해 Container의 서브 클래스를 만들기 보다는 앞서 언급한 위젯들 혹은 그외 다른 간단한 위젯들을 참신한 방법으로 조합할 수 있습니다.

 

가능한 조합의 수를 최대화하기 위해 클래스 계층 구조는 얕고 넓습니다.

다른 위젯들과 함께 구성하는 방식으로 위젯의 레이아웃을 조작할 수 있습니다.

예를 들어, 위젯을 가운데로 위치시키려면 그 위젯을 Center 위젯으로 감싸면 됩니다.

패딩, 정렬, 행, 열, 그리드와 같은 여러 레이아웃 위젯들이 있는데, 이러한 레이아웃 위젯들은 그 자체로 시각적 표현을 갖고 있지는 않습니다.

이들의 유일한 목적은 다른 위젯의 레이아웃을 제어하는 것이기 때문입니다. 만약 어떤 위젯이 어째서 이렇게 렌더링된건지 궁금하다면, 인근에 위치한 다른 위젯들을 살펴보면 알 수 있습니다.

 

Flutter 프레임워크는 각각의 층이 이전 층에 의해 빌드되는 일련의 층으로 구성되어 있습니다.

 

프레임워크의 상위 레이어로 갈수록 하위 레이어보다 더 빈번히 사용됩니다. 

Flutter의 계층화된 프레임워크를 구성하는 전체 라이브러리는 API 문서에서 확인할 수 있습니다.

이러한 설계의 목표는 개발자로 하여금 더 적은 코드로 더 많은 일을 할 수 있게 하는 것입니다.

예를 들어, 머티리얼 계층은 위젯 계층의 기본적인 위젯들을 조합하여 만들어지고, 위젯 계층은 렌더링 계층의 하위 레벨 오브젝트들의 조합으로 만들어집니다.

계층들은 앱을 만드는데 많은 옵션을 제공합니다. 

프레임워크의 풍부한 표현력을 활용할 수 있는 커스터마이즈한 접근법을 선택하거나 위젯 계층의 블럭들을 사용하세요, 혹은 이것들을 조화롭게 잘 조합하여 사용하세요. 

Flutter가 제공하는 자체 위젯들을 사용하거나, Flutter 팀에서 프레임워크 개발할 때 사용한 것과 동일한 도구와 기술들을 갖고 직접 커스텀 위젯도 만들 수 있습니다.

모든 것은 공개되어 있습니다. 프레임워크의 하위 계층을 뜯어보지 않고도 상위 레벨의 위젯 컨셉만으로도 생산성을 높일 수 있습니다.

 

반응형
반응형

다트는 동기/비동기 프로그래밍을 지원한다.

동기 : 요청을 하고 나서 응답이 올 때까지 기다렸다가 응답.

비동기 : 요청을 하고 나서 응답을 받지 않아도 다음 코드를 진행. 추후에 응답이 오면 처리.

 

Future

- Future 클래스 : 미래에 제너릭으로 값을 받아옴.

// 일정 시간 후 콜백 함수 실행.
// Future.delayed

void main() {
  print("실행 시작");
  Future.delayed(Duration(seconds: 3), (){
    print('3초 후 실행합니다.');
  });
  print("실행 완료?");
}

// 실행 결과(비동기로 동작)
실행 시작
실행 완료?
3초 후 실행합니다.

 

async, await

- 코드를 순서대로 실행시키기 위해 사용

void main() {
  addNumbers(1, 1);
}

// async 키워드는 함수 매개변수 정의와 바디 사이에 입력.
void addNumbers(int number1, int number2) async {
  print('$number1 + $number2 계산 시작!');

  // await는 대기하고 싶은 비동기 함수 앞에 입력.
  await Future.delayed(Duration(seconds: 3), (){
    print('$number1 + $number2 = ${number1 + number2}');
  });

  print('$number1 + $number2 코드 실행 끝');
}

// 실행 결과
1 + 1 계산 시작!
1 + 1 = 2
1 + 1 코드 실행 끝

 

비동기적으로 동작하는 지 확인

void main() {
  addNumbers(1, 1);
  addNumbers(2, 2);
}

Future<void> addNumbers(int number1, int number2) async {
  print('$number1 + $number2 계산 시작!');

  await Future.delayed(Duration(seconds: 3), (){
    print('$number1 + $number2 = ${number1 + number2}');
  });

  print('$number1 + $number2 코드 실행 끝');
}

// 실행 결과
1 + 1 계산 시작!
2 + 2 계산 시작!
1 + 1 = 2
1 + 1 코드 실행 끝
2 + 2 = 4
2 + 2 코드 실행 끝

 

두 함수를 순차적으로 실행하고 싶다면...

// main 함수에 async, await 사용.
void main() async {
  await addNumbers(1, 1);
  await addNumbers(2, 2);
}

Future<void> addNumbers(int number1, int number2) async {
  print('$number1 + $number2 계산 시작!');

  await Future.delayed(Duration(seconds: 3), (){
    print('$number1 + $number2 = ${number1 + number2}');
  });

  print('$number1 + $number2 코드 실행 끝');
}

// 실행 결과
1 + 1 계산 시작!
1 + 1 = 2
1 + 1 코드 실행 끝
2 + 2 계산 시작!
2 + 2 = 4
2 + 2 코드 실행 끝

 

결과 값을 비동기로 리턴 받고 싶다면...

void main() async {
  final result = await addNumbers(1, 1);
  print('결과값 $result');  // 일반 함수와 동일하게 반환값을 받을 수 있음
  final result2 = await addNumbers(2, 2);
  print('결과값 $result2');
}

Future<int> addNumbers(int number1, int number2) async {
  print('$number1 + $number2 계산 시작!');

  await Future.delayed(Duration(seconds: 3), (){
    print('$number1 + $number2 = ${number1 + number2}');
  });

  print('$number1 + $number2 코드 실행 끝');

  return number1 + number2;
}

//
1 + 1 계산 시작!
1 + 1 = 2
1 + 1 코드 실행 끝
결과값 2
2 + 2 계산 시작!
2 + 2 = 4
2 + 2 코드 실행 끝
결과값 4

 

 

Stream

- Future 는 결과값을 한번 리턴.

- 지속적으로 리턴받고 싶을 때는 Stream 을 사용.

- Stream 은 한번 Listen 하면 지속적으로 값을 받아온다.

import 'dart:async';

void main() {
  final controller = StreamController();  // StreamController 선언
  final stream = controller.stream;  // Stream 가져오기

  // Stream에 listen() 함수를 실행하면 값이 주입될 때마다 콜백 함수를 실행
  final streamListener1 = stream.listen((val) {
    print(val);
  });

  // Stream에 값을 주입할 때는 sink.add() 함수를 실행
  controller.sink.add(1);
  controller.sink.add(2);
  controller.sink.add(3);
  controller.sink.add(4);
}

// 실행 결과
1
2
3
4

 

Broadcasting

- Stream 을 여러번 Listen 하기

import 'dart:async';

void main() {
  final controller = StreamController();

  // 여러 번 listen할 수 있는 Broadcast Stream 객체 생성
  final stream = controller.stream.asBroadcastStream();

  // listen() 함수
  final streamListener1 = stream.listen((val) {
    print('listening 1');
    print(val);
  });

  // listen() 함수 추갸.
  final streamListener2 = stream.listen((val) {
    print('listening 2');
    print(val);
  });

  // add()를 실행할 때마다 listen()하는 모든 콜백 함수에 값이 주입
  controller.sink.add(1);
  controller.sink.add(2);
  controller.sink.add(3);

}

// 실행 결과.
listening 1
1
listening 2
1
listening 1
2
listening 2
2
listening 1
3
listening 2
3

 

함수로 Stream 반환하기

- 이건 잘 모르겠음. --;;

import 'dart:async';

// Stream을 반환하는 함수는 async*로 선언합니다.
Stream<String> calculate() async* {
  for (int i = 0; i < 5; i++) {
    // StreamController의 add()처럼 yield 키워드를 이용해서 값 반환
    yield 'i = $i';
    await Future.delayed(Duration(seconds: 1));
  }
}

void playStream() {
  // StreamController와 마찬가지로 listen() 함수로 콜백 함수 입력
  calculate().listen((val) {
    print(val);
  });
}

void main() {
  playStream();
}

// 실행 결과(1초에 한줄씩 출력)
i = 0
i = 1
i = 2
i = 3
i = 4

 

이번에는 비동기 프로그래밍에 대해서 알아봤다.

점점 어려워지는구만..ㅋㅋ

반응형
반응형

다트 언어는 객체지향 프로그래밍을 지원한다.

 

클래스

// class 정의.
class Person {

	// class 종속 변수
	String name = '이름';
    
    // class 종속 함수 = 메소드
    // 내부 속성을 사용할 때 this 키워드 사용.
    void sayName() {
    	print('My name is ${this.name}');
    }
    
}

 

인스턴스 생성

void main() {
	// 인스턴스 생성
	Person person = Person();
    
    // 메소드 실행.
    person.sayName();
}

 

생성자

class Person {
	// 생성자에서 입력 받는 변수들은 일반적으로 final 키워드 사용.
	final String name;
    
    // 생성자 선언. class 와 같은 이름.
    // 매개변수 지정
    Person(String name) : this.name = name;
    
    // this 를 사용할 경우.
    // 해당되는 변수에 자동을 매개변수가 저장.
    Person(this.name);
    
    void sayName() {
    	print('My name is ${this.name}');
    }
    
}

void main() {
	Persion person = Person('홍길동');
}

 

네임드 생성자

class Person {
	final String name;
    final int age;
    
    // 1개 이상의 변수를 저장할때는 , 기호로 연결.
    Person(String name, int age)
    	: this.name = name,
          this.age = age;
    
    // 네임드 생성자
    Person.fromMap(Map<String, dynamic> map)
    	: this.name = map['name'],
          this.age = map['age'];
    
    void sayName() {
    	print('My name is ${this.name}');
    }
    
}

void main() {
	Persion person = Person('홍길동', 20);
    Persion hong = Person.fromMap({
    	'name' : '홍길동',
        'age' : 20,
    });
}

 

private 변수

class Person {
	// '_' 로 시작하면 private 변수 선언.
	String _name;
    
    Person(this._name);
    
    void sayName() {
    	print('My name is ${this._name}');
    }
    
}

void main() {
	Persion person = Person('홍길동');
    print(person._name); // 같은 파일에서는 에러가 발생하지 않지만 다른 파일에서 사용시 에러 발생.
}

 

Getter / Setter

class Person {
	String _name = 'hong';
    
    // get 키워드를 사용하여 getter 명시
    // 매개변수를 받지 않음.
    String get name {
    	return this._name;
    }
    
    // set 키워드를 사용하여 setter 명시
    // 매개변수로 하나의 변수를 받음.
    set name(String name) {
    	this._name = name;
    }
    
}

void main() {
	Persion person = Person();
    person.name = '홍길동'; // setter
    print(person.name); // getter
}

 

상속

class Person {
	final String name;
    
    Person(this.name);
    
    void sayName() {
    	print('My name is ${name}.');
    }
}

// 상속
class Man extends Person {
	// 상속 받은 생성자
    // super 는 부모 클래스를 의미한다.
	Man(String name) : super(name);
    
    void sayMan() {
    	print('I am a man');
    }
}

void main() {
	Man man = Man('홍길동');
	print(man.sayName()); // 부모한테 물려받은 메소드
    print(man.sayMan()); // 자식이 추가한 메소드
}

 

오버라이드

class Person {
	final String name;
    
    Person(this.name);
    
    void sayName() {
    	print('My name is ${name}.');
    }
}

class Girl extends Person {
    // super 키워드를 직접 사용할 수 있음.
	Girl(super.name);
    
    @override
    void sayName() {
    	print('My name is ${name} and I am a girl');
    }
}

void main() {
	Girl girl = Girl('영희');
	print(girl.sayName()); // override 된 메소드
}

 

인터페이스

// implements 키워드를 사용하면 클래스를 인터페이스로 사용할 수 있다.
class Girl implements Person {
    final String name;
    
	Girl(super.name);
    
    // 인터페이스로 사용할 때는 모든 메소드를 재정의 해야한다.
    void sayName() {
    	print('My name is ${name}');
    }
}

void main() {
	Girl girl = Girl('영희');
	print(girl.sayName());
}

 

믹스인???

 - 이건 잘 모르겠다... --;;;

 

추상 클래스

 - 인스턴스화 할 필요가 없을 경우에 사용

// abstract 키워드를 사용하여 추상 클래스 정의.
abstract class Person {
	final String name;
    
    // 생성자 선언
    Person(this.name);
    
    // 추상 메소드 선언.
    void sayName();
}

// implements 키워드를 사용하여 추상 클래스를 구현.
// 생성자를 비롯하여 모든 메소드를 정의해야 한다.
class Girl implements Person {
	final String name;

    // super 키워드를 직접 사용할 수 있음.
	Girl(this.name);
    
    void sayName() {
    	print('My name is ${name} and I am a girl');
    }
}

void main() {
	Girl girl = Girl('영희');
    print(girl.sayName());
}

 

제너릭

// 제너릭
// 특정 변수의 타입을 제한하고 싶지 않을 때 사용.
// 인스턴스화 할 때 입력받을 타입을 T 로 지정.
class Generate<T> {
	// 데이터 타입을 인스턴스화 할 때 지정한 타입으로 사용.
	final T data;
    
    Generate({
    	required this.data,
    });
}

void main() {
	// 제너릭에 입력된 값을 통해 data 변수의 타입이 자동으로 유추.
	final gen = Generate<List<int>> (data : [1, 2, 3]);
    print(gen.data.reduce((v,e) => v + e); // 6
}

 

static

class Count {
	// static 은 클래스 자체에 귀속
	static int i = 0;
    
    // 생성자가 호출될때 마다 i 증가.
    Count() {
    	i++;
        print(i);
    }
}

void main() {
	Count c1 = Count(); // 1
    Count c2 = Count(); // 2
    Count c3 = Count(); // 3
}

 

Cascade

class Person {
	final String name;
    final int age;
    
    Person(this.name, this.age);
    
    void sayName() {
    	print('My name is ${this.name}');
    }
    
    void sayAge() {
    	print('My age is ${this.age}');
    }
}

void main() {
	// cascade 연산자 ..
    // 인스턴스의 속성이나 메소드를 연속해서 사용하는 것.
	Person person = Person('홍길동', 20)
    	..sayName()
        ..sayAge();
}

 

오늘은 다트의 객체지향 프로그래밍에 대해서 공부했다!!

 

반응형
반응형

플러터는 다트(Dart) 언어를 사용합니다.

다트를 알아야 플러터로 앱 개발이 가능하므로 다트를 공부해야합니다.

다트는 구글에서 개발한 프로그래밍 언어입니다.

다트는 모바일이나 데스크탑 기기를 타겟으로 하는 네이티브 플랫폼과 웹을 타켓으로 하는 웹 플랫폼으로 컴파일 할 수 있습니다.

다트 공부하기

1. 다트패드에서 공부하기

다트패드 홈페이지에서 코드 작성 및 실행 가능합니다.
 

DartPad

 

dartpad.dev

코드 작성 후 Run 버튼을 클릭하여 실행 결과를 확인 할 수 있다.

 

2. 안드로이드 스튜디오에서 공부하기

File -> New -> New Flutter Project ... 메뉴를 클릭하여 플러터 프로젝트를 생성한다.

lib/main.dart 파일에 코드를 작성 후 안드로이드 스튜디오 하단의 터미널 탭에서 dart lib/main.dart 명령어를 실행한다.

 

 

기초 문법

메인 함수

void main() {
	// 한줄 주석
    
    /* 시작기호, 끝 기호 */
    /* 여러 줄 주석
    * 
    *
    * */
    
    /// 슬래시 세 개를 사용하면 문서 주석을 작성할 수 있습니다.
    
}

 

변수 선언

// 변수 타입
String(문자열), int(정수형), double(실수형), bool(불리언 true/false)
String s = '';
int i = 1;
double d = 1.0;
bool b = true;

// 자동으로 타입을 추론. 한번 추론된 타입은 고정됨.
var name = '이름';

// 추후에 타입이 바뀌면 에러
name = 1; // 에러

// dynamic 키워드를 사용하면 변수 타입을 고정하지 않고 사용 가능.
dynamic d_name = '다이내믹';
d_name = 1;

// final, const 는 처음 선언 후 값 변경이 불가하다.
final String f_str = 'final string';
f_str = 'new string'; // 에러 발생

const String c_str = 'const string';
c_str = 'new const'; // 에러 발생

// final 은 런타임, const 는 빌드타임 상수이다.
// DateTime.now() 는 실행되는 순간(런타임 시) 값이 정해진다.
final DateTime f_now = DateTime.now();
const DateTime c_now = DateTime.now(); // 에러 발생

// 컬렉션
// List
List<String> list = ['s1', 's2', 's3'];
print(list[3]); // s3
list.add('s4');
final list_where = list.where((str) => str == 's1' || str == 's4'); // Iterable (s1, s4)
print(list_where.toList()); // [s1, s4]
final list_map = list.map((str) => 'new $str'); // Iterable (new s1, new s2, new s3, new s4);
final list_reduce = list.reduce((v, e) => v + ', ' + e); // (반환 타입이 String) s1, s2, s3, s4
final list_fold = list.fold(0, (v, e) => v + e.length); // (반환 타입 아무거나 가능) 8

// Map
Map<String, String> map = {
	'a' : 'a1',
    'b' : 'b2',
    'c' : 'c3',
};
print(map['b']); // b2
print(map.keys); // Iterable (a, b, c)
print(map.values); // Iterable (a1, b2, c3)

// Set
Set set = {'s1', 's2', 's3'};
set.contain('s2'); // true
set.toList(); // Set to List
Set.from(list); // Set from List

// enum
enum Status {
	ready,
    play,
    done,
}

Status status = Status.ready;
print(status); // Status.ready

 

연산자

// 사칙연산
+
-
*
/ // 몫
% // 나머지
++
--
+=
-=
*=
/=


// null 관련 연산자
// nallable
double? number1 = 1;

// not null
double number2 = null; // 에러 발생

// null 로 초기화
double? number;

// null 이면 할당.
number ??= 3; // 3

// not null 이면 할당하지 않음.
number ??= 4; // 3


// 값 비교
>
<
>=
<=
==
!=


// 타입 비교
print(number is int); // false
print(number is double); // true
print(number is! int); // true
print(number is! double); // false


// 논리 연산자
&&
||

 

제어문

if
else if
else

switch() {
	case 1 :
    	print();
    	break;
    default:
    	print();
}

for(int i=0; i < 10; i++) {
	print(i);
}

List<int> list = [1,2,3];
for(int n in list) {
	print(n);
}

while() {
}

do {
} while()

 

함수와 typedef

void main() {
	// 고정된 매개변수(포지셔널 파라미터)
      print(addTwoNumbers1(2, 3));

      // 이름이 있는 매개변수(네임드 파라미터)
      print(addTwoNumbers2(a:2, b:3));

      // 고정된 매개변수 기본값 지정
      print(addTwoNumbers3(2));
      print(addTwoNumbers3(2, 1));

      // 이름이 있는 매개변수 기본값 지정
      print(addTwoNumbers4(a:2));
      print(addTwoNumbers4(a:2, b:1));


      // typedef 는 일반적인 변수의 type 처럼 사용.
      Operation oper = add;
      oper(1, 2);

      oper = subtract;
      subtract(5, 2);

      calculate(3, 4, add);
}

// 함수의 시그니처 정의.
typedef Operation = void Function(int x, int y);

void add(int x, int y) {
  print('Add Result = ${x + y}');
}

void subtract(int x, int y) {
  print('Subtract Result = ${x - y}');
}

// dart 에서 함수는 일급 객체(일급 시민)이므로 함수를 값처럼 사용 가능.
// typedef 으로 선언한 함수를 매개변수로 사용 가능.
void calculate(int x, int y, Operation oper) {
  oper(x, y);
}

int addTwoNumbers1(int a, int b) {
  return a + b;
}

int addTwoNumbers2({required int a, required int b}) {
  return a + b;
}

int addTwoNumbers3(int a, [int b=3]) {
  return a + b;
}

int addTwoNumbers4({required int a, int b=3}) {
  return a + b;
}

 

기본 문법은 이정도로 정리하겠다.^^

반응형
반응형

본격적인 개발을 위한 도구인 안드로이드 스튜디오를 설치해보자.

공식 사이트에서 다운로드 한다.
 

Android 개발자  |  Android Developers

Android 앱 개발자를 위한 공식 사이트입니다. Android SDK 도구 및 API 문서를 제공합니다.

developer.android.com

 

그 다음 Flutter 플러그인을 설치한다.

File -> Settings 메뉴에서 Plugins 에서 flutter 검색 후 install 한다.

 

이제 개발을 위한 준비를 마쳤다.

본격적으로~~ 개발을 해보자!!

 

반응형
반응형

안드로이드와 iOS 앱을 만들수 있는 플러터를 알아보기로 했다.

먼저, 설치 부터 시작!

공식 사이트에서 Get Started 클릭.
※ 한글 사이트도 제공하고 있으니 참고하면 좋을 것 같다.
자신의 OS에 맞게 다운로드 한다.(Windows)


SDK 를 다운받아 원하는 위치에 압축을 풀면 된다.

현재 버전은 3.7.10

 

플러터 명령어를 실행하기 위해 환경 변수 설정!

윈도우 -> 설정
윈도우 - 설정



설정 창에서 "시스템 환경 변수" 검색



시스템 속성 창에서 "환경 변수" 클릭



시스템 환경 변수 추가
환경 변수 창에서 "시스템 변수"의 Path 편집 클릭
환경 변수 편집 창에서 "새로 만들기" 클릭하여 "플러터 SDK 압축 푼 디렉토리\bin" 추가 


cmd 창에서 설치 버전 확인

 

반응형

+ Recent posts