위젯은 화면에 보일 뷰를 설명하는 객체입니다. 즉, 화면과 관련된 모든 것이 위젯입니다. 플러터로 앱을 만들 때 기본 위젯과 사용자가 작성하는 위젯을 조합해서 화면을 구성합니다.
아래 코드에서는 runApp() 함수에 플러터가 기본으로 제공하는 Center라는 위젯을 전달했습니다. Center 위젯에 텍스트를 나타내는 Text 위젯을 포함했습니다.
// runApp() 함수로 루트 위젯 등록하기
import 'package:flutter/material.dart';
void main() {
runApp(
Center(
child: Text(
'Hello, world!',
),
),
);
}
runApp() 함수는 전달받은 위젯을 위젯 트리의 루트로 만듭니다. 그리고 플러터 프레임워크는 이 루트 위젯으로 화면을 덮습니다. 플러터 앱의 화면은 이처럼 필요한 위젯을 계층으로 나열해서 구성합니다.
이번에는 위젯 클래스를 직접 구현해서 화면을 만들어 보겠습니다.
// 화면 구성 예
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Text'),
),
body : Center(child: GestureDetector(child: Text('HelloWorld'))),
),
);
}
}
MyApp 클래스는 이 앱의 화면 전체를 구성하는 위젯으로 StatelessWidget 클래스를 상속받아 선언했습니다. StatelessWidget을 상속받은 위젯은 화면에 보일 뷰를 갱신할 수 없습니다. 즉, 정적인 화면이 됩니다.
위젯 클래스의 주요 작업은 다른 위젯을 계층으로 조합해 build() 함수를 구현하는 것입니다. 앞의 예에서는 다음 7개위젯을 계층으로 조합해 MyApp 클래스의 build() 함수를 구현했습니다.
- MaterialApp: 머터리얼 디자인 적용
- Scaffold: 화면 구조 설계
- AppBar: 화면 위쪽 앱바 구성
- Text: 앱바의 제목
- Center: 가운데 정렬
- GestureDetector: 사용자 이벤트 처리
- Text: 본문에 문자열 출력
결국 플러터에서는 화면에 무언가를 출력하는 클래스뿐만 아니라 화면의 구조를 설계하거나 사용자 이벤트를 처리하는 클래스, 요소를 정렬하는 클래스 등 화면과 관련된 모든 것이 위젯입니다.
플러터의 위젯은 모두 Widget의 자식 클래스입니다. Widget과 Text, Center 클래스의 계층을 나타내면 다음과 같습니다.
- Object => DiagnosticableTree => Widget
- Object => DiagnosticableTree => Widget => StatelessWidget => Text
- Object => DiagnosticableTree => Widget => RenderObjectWidget => SingleChildRenderObjectWidget => Align => Center
선언형 프로그래밍으로 화면을 구성한다
플러터는 선언형 프로그래밍으로 화면을 구성합니다. 선언형 프로그래밍과 반대되는 개념은 명령형 프로그래밍입니다. 선언형 프로그래밍은 많은 프런트엔드 프레임워크가 제공하는 기법이며, 플러터 공식 문서를 보면 리액트 프레임워크에서 영감을 얻어 설계했다고 밝히고 있습니다.
명령형은 개발자가 화면 구성과 관련된 모든 코드를 작성합니다. 예를 들어 화면에 문자열을 출력한다면 데이터뿐만 아니라 위치와 색상, 배경색, 크기 등 많은 정보를 코드로 작성해야합니다. 따라서 많은 함수가 필요합니다. 결국 명령형으로 화면을 구성하면 코드가 길어질 수 밖에 없으며 화면과 관련된 많은 API를 알고 있어야 합니다.
반면에 플러터가 채택한 선언형은 화면 구성 정보만 작성하면 됩니다. 즉, 위젯의 정보만 제시하면 됩니다. 그러면 프레임워크가 알아서 API를 이용해 화면을 출력해 줍니다.
이 외에도 명령형 대신 선언형을 쓰면 코드 재사용성, 불변성으로 인한 동시성 오류방지, 쉬운 코드 관리, 높은 생산성 등 여러 가지 이점이 있습니다.
위젯은 불변이다
플러터의 위젯은 불변 객체입니다. 즉, 객체를 생성한 후 상태를 바꿀 수 없습니다. 따라서 처음 생성할 때의 정보가 화면에 나옵니다. 만약 화면을 새 데이터로 갱신하려면 새로운 위젯 객체를 만들어야 합니다. 이런 개념을 정리해 두면 이후에 위젯의 구조와 동작 원리를 이해할 때 도움이 됩니다.
위젯 객체를 다시 생성한다는 게 비효율적이지 않나요?
위젯은 위젯일 뿐 실제 화면이 아닙니다. 단순히 화면에 출력할 정보를 가지는 객체이지, 실제 화면을 출력하는 객체는 아닙니다. 실제 화면을 출력하는 객체는 플러터 프레임워크에서 따로 만들어 사용하므로 화면을 갱신할 때 단순히 정보만 가진 객체를 다시 생성하는 것으로 이애하면 됩니다.
'Flutter' 카테고리의 다른 글
정적인 화면 만들기 (0) | 2024.11.15 |
---|---|
위젯 트리 알아보기 (0) | 2024.11.15 |
멤버를 공유하는 믹스인 (1) | 2024.11.15 |
추상 클래스와 인터페이스 (1) | 2024.11.15 |
상속 알아보기 (0) | 2024.11.14 |
위젯은 화면에 보일 뷰를 설명하는 객체입니다. 즉, 화면과 관련된 모든 것이 위젯입니다. 플러터로 앱을 만들 때 기본 위젯과 사용자가 작성하는 위젯을 조합해서 화면을 구성합니다.
아래 코드에서는 runApp() 함수에 플러터가 기본으로 제공하는 Center라는 위젯을 전달했습니다. Center 위젯에 텍스트를 나타내는 Text 위젯을 포함했습니다.
// runApp() 함수로 루트 위젯 등록하기
import 'package:flutter/material.dart';
void main() {
runApp(
Center(
child: Text(
'Hello, world!',
),
),
);
}
runApp() 함수는 전달받은 위젯을 위젯 트리의 루트로 만듭니다. 그리고 플러터 프레임워크는 이 루트 위젯으로 화면을 덮습니다. 플러터 앱의 화면은 이처럼 필요한 위젯을 계층으로 나열해서 구성합니다.
이번에는 위젯 클래스를 직접 구현해서 화면을 만들어 보겠습니다.
// 화면 구성 예
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Text'),
),
body : Center(child: GestureDetector(child: Text('HelloWorld'))),
),
);
}
}
MyApp 클래스는 이 앱의 화면 전체를 구성하는 위젯으로 StatelessWidget 클래스를 상속받아 선언했습니다. StatelessWidget을 상속받은 위젯은 화면에 보일 뷰를 갱신할 수 없습니다. 즉, 정적인 화면이 됩니다.
위젯 클래스의 주요 작업은 다른 위젯을 계층으로 조합해 build() 함수를 구현하는 것입니다. 앞의 예에서는 다음 7개위젯을 계층으로 조합해 MyApp 클래스의 build() 함수를 구현했습니다.
- MaterialApp: 머터리얼 디자인 적용
- Scaffold: 화면 구조 설계
- AppBar: 화면 위쪽 앱바 구성
- Text: 앱바의 제목
- Center: 가운데 정렬
- GestureDetector: 사용자 이벤트 처리
- Text: 본문에 문자열 출력
결국 플러터에서는 화면에 무언가를 출력하는 클래스뿐만 아니라 화면의 구조를 설계하거나 사용자 이벤트를 처리하는 클래스, 요소를 정렬하는 클래스 등 화면과 관련된 모든 것이 위젯입니다.
플러터의 위젯은 모두 Widget의 자식 클래스입니다. Widget과 Text, Center 클래스의 계층을 나타내면 다음과 같습니다.
- Object => DiagnosticableTree => Widget
- Object => DiagnosticableTree => Widget => StatelessWidget => Text
- Object => DiagnosticableTree => Widget => RenderObjectWidget => SingleChildRenderObjectWidget => Align => Center
선언형 프로그래밍으로 화면을 구성한다
플러터는 선언형 프로그래밍으로 화면을 구성합니다. 선언형 프로그래밍과 반대되는 개념은 명령형 프로그래밍입니다. 선언형 프로그래밍은 많은 프런트엔드 프레임워크가 제공하는 기법이며, 플러터 공식 문서를 보면 리액트 프레임워크에서 영감을 얻어 설계했다고 밝히고 있습니다.
명령형은 개발자가 화면 구성과 관련된 모든 코드를 작성합니다. 예를 들어 화면에 문자열을 출력한다면 데이터뿐만 아니라 위치와 색상, 배경색, 크기 등 많은 정보를 코드로 작성해야합니다. 따라서 많은 함수가 필요합니다. 결국 명령형으로 화면을 구성하면 코드가 길어질 수 밖에 없으며 화면과 관련된 많은 API를 알고 있어야 합니다.
반면에 플러터가 채택한 선언형은 화면 구성 정보만 작성하면 됩니다. 즉, 위젯의 정보만 제시하면 됩니다. 그러면 프레임워크가 알아서 API를 이용해 화면을 출력해 줍니다.
이 외에도 명령형 대신 선언형을 쓰면 코드 재사용성, 불변성으로 인한 동시성 오류방지, 쉬운 코드 관리, 높은 생산성 등 여러 가지 이점이 있습니다.
위젯은 불변이다
플러터의 위젯은 불변 객체입니다. 즉, 객체를 생성한 후 상태를 바꿀 수 없습니다. 따라서 처음 생성할 때의 정보가 화면에 나옵니다. 만약 화면을 새 데이터로 갱신하려면 새로운 위젯 객체를 만들어야 합니다. 이런 개념을 정리해 두면 이후에 위젯의 구조와 동작 원리를 이해할 때 도움이 됩니다.
위젯 객체를 다시 생성한다는 게 비효율적이지 않나요?
위젯은 위젯일 뿐 실제 화면이 아닙니다. 단순히 화면에 출력할 정보를 가지는 객체이지, 실제 화면을 출력하는 객체는 아닙니다. 실제 화면을 출력하는 객체는 플러터 프레임워크에서 따로 만들어 사용하므로 화면을 갱신할 때 단순히 정보만 가진 객체를 다시 생성하는 것으로 이애하면 됩니다.
'Flutter' 카테고리의 다른 글
정적인 화면 만들기 (0) | 2024.11.15 |
---|---|
위젯 트리 알아보기 (0) | 2024.11.15 |
멤버를 공유하는 믹스인 (1) | 2024.11.15 |
추상 클래스와 인터페이스 (1) | 2024.11.15 |
상속 알아보기 (0) | 2024.11.14 |