플러터의 장점은 UI 배치가 매우 쉬운 배려가 되어 있는 언어라는 점입니다. 위젯 형태로 제공되는 기본 UI 구성 요소가 많이 제공되고, 각각의 위젯 내부에 배치할 수 있는 속성에 위젯 클래스를 배치하기만 하면 UI 구성이 잘 됩니다. 이 장점으로 인해 저도 아주 훌륭한 혜택을 받고 있습니다. 다트와 플러터에서 제공되는 제작사가 만든 UI 위젯뿐아니라, 사용자 생태계에서 제공되는 패키지도 쓰면 아주 쉽게 UI 배치가 되서 좋습니다.
플러터는 화면을 채우는 위젯에 하위 위젯을 배치하면서 UI 구성을 설계해갑니다. main() 함수에서 runApp()으로 호출되는 최상위 위젯 아래에 return 문을 확장해가면서 코딩을 할 수 있습니다.
import 'package:flutter/material.dart';
void main() {
runApp(
const Center(
child: Text(
'Hello, world!',
),
),
);
}
이 파일을 실행하면 화면에 Hello, world!가 뜰 것입니다. 다른 언어처럼 실행 첫진입 지점을 포함한 파일이 읽히게 되고, 이 파일에 정의된 main() 함수에서 runApp() 함수가 실행됩니다. 위 예제에서는 다른 클래스를 return하지 않고 즉시 Center() 위젯을 불러와서 그 안에 텍스트를 표시하는 Text() 위젯을 배치해서 코딩이 되었습니다.
child: Text(
'Hello, world!',
),
주목할 것은 Center() 함수 안에 child: 라고 표시된 부분입니다. 플러터에서 제공하는 위젯들은 계층구조를 가지고 배치가 되는데, 배치하는 위치에는 십중팔구 타위젯을 배치할 수 있게 설계된 속성이 옵니다. 위의 경우 child: 라고 표시된 부분이 그러한데요. Center() 위젯이 설계될 당시에 child: 속성을 써서 타위젯을 배치하게 되게 해둔 것입니다. 여기에 올 수 있는 위젯이라면 다 올 수 있습니다. (플러터 API doc에 나옴) 예제에서는 화면 중앙에 배치하기 위해 Center() 위젯을 최상위 위젯으로 두었고 그 안에 Text() 위젯을 써서 문자열을 표시하게 해두었습니다.
때로는 MaterialApp()과 Scaffold() 같은 위젯을 return 해서 보다 더 규모있는 앱을 만들기도 하죠.
이 경우 유의할 것은 child: 와 흡사하면서 여러개의 위젯을 병렬해서 배치가 가능한 위젯들이 있다는 것입니다. Column() 이나 Row()가 그 예로, child: 대신 children: [ ] 과 같은 속성이 제공되면, [ ] 안에 여러 위젯을 쉼표로 구분하면서 배치할 수 있게 해서 레이아웃 구성에 효율이 있게 될때가 많습니다.
이 경우 특히 좋은 것은 전역변수로 지정한 변수에 상태값을 대응시켜서 같은 자리에 내용만 바꿔 위젯 표시를 하고 싶을때 가능해게 해준다는 것입니다.
Column(
children: <Widget>[
Container(child: ... ),
const SizedBox(height: 30.0),
_conditional == 0
? ChatBubble(
child: Text('좋은 아침!')
: _conditional == 1
? ChatBubble(
child: Text('맛점하세요!')
: _condiitonal == 2
? ChatBubble(
child: Text('좋은 꿈 꾸세요!')
: const SizedBox(height: 5.0),
const SizedBox(height: 60.0),
Center(child: Image.asset('assets/images/day_and_night.jpg')
],
),
위에 예에서처럼 children: [ ] 내부에 특별한 방법으로 채워주면 실행이 가능한 기능이 있습니다. setState() 함수로 _conditional 값을 조정하면 _conditional 값에 따라 같은 위치에 Text() 값만 바뀌어 표시할 수 있습니다. 조정된 _conditional 이 충족되는 값일때 : 로 구분한 영역의 코드만 재실행되는 것입니다. 이렇게 하면 안내 메시지 표시할때 route 기능 없이도 같은 위치에 다른 표시를 할 수 있게 됩니다.
예를 들면 GestureDectector() 와 같이 onTap: 속성이 제공되는 위젯에서 사용자가 탭한 것을 받아서 setState() 함수로 _conditional 값을 바꿔주면 실행이 됩니다.
이 경우 _conditional 변수가 전역변수여야 하고, setState() 함수가 실행가능해야 합니다. (setState() 실행 가능한 한 조건은 createState() 함수로 State 클래스가 작성되어 있어야 합니다)
설명을 잘한지 모르는데, 일단 흐름은 이해가 될 것입니다. setState() 함수를 실행하는 코드 예시는 아래 링크에서 힌트를 얻어보세요.
https://docs.flutter.dev/development/ui/interactive
참고가 되셨을 것 입니다.