플러터 UI입문
chapter 7 공부 내용!
해당 챕터에서 새롭게 배운 내용 위주로 정리해보겠다.
SizedBox()를 활용해서 위젯 간 여백을 줘야 할 때가 많다. 이 때마다 임의로 사이즈를 주면 앱 디자인이 중구난방이 될 가능성이 크다. 그러므로 아래와 같은 방법을 활용해보자.
size.dart 파일을 만들어서
small_gap = 5;
medium_gap = 10;
~~이런 식으로 작성하고 임포트해서 쓰는 거임!
필요한 화면이 몇개인가? 화면 당 위젯은 어떻게 배치할 것인가
화면 라우팅은 MaterialApp 객체에 적용시키면 된다. 적용 방법은 아래와 같다
MaterialApp(
home: MyHome(),
routes: <String, WidgetBuilder> {
'/a': (BuildContext context) => LoginPage(),
'/b': (BuildContext context) => HomePage()
}
)
MaterialApp의 routes 파라미터에 Map 객체 형태로 넘겨주면 된다. key에는 라우팅 경로, value에는 WigetBuilder 함수를 넘겨주면 된다.
builder의 전형적 형태: context를 인자로, 위젯을 리턴값으로!
initialRoute: "/login",
routes: {
"/login": (context) => LoginPage(),
"/home" : (context) => HomePage(),
}
마찬가지로 MaterialApp의 인자 중, initialRoute에 기본이 되는 라우팅 경로를 설정해 놓으면 앱을 켰을 때 처음 보일 화면을 지정할 수 있다.
예를 들어 TextFormField를 넣어야 할 때(유저가 글을 작성해야 하는 경우), 아래 키보드 창이 올라오면 화면을 그릴 수 있는 영역이 줄어든다. 이 때 Column 위젯은 그림을 그릴 수 있는 영역이 줄어들어 즉, 그림을 그릴 수 없는 영역(Inset영역)이 생겨 overflow 오류가 발생한다. 이에 반해 스크롤을 주는 ListView는 아주 유연하게 대응이 가능하다.
그러므로 텍스트를 입력하거나 하는 이유로 화면상 변동이 있는 페이지에서는 무조건 ListView 위젯을 사요할 것!
SVG 파일은 벡터 이미지 파일. 벡터 이미는 파일이 커져도 깨지질 않음.
위 라이브러리를 활용하면 벡터 이미지 파일을 손쉽게 다룰 수 있음.
아래는 사용 예시
import 'package:flutter_svg/flutter_svg.dart';
(중략)
@override
Widget build(BuildContext context) {
return Column(
children: [
SvgPicture.asset(
"assets/logo.svg",
height: 70,
width: 70,
),
.....~~
TextFormField => TextField 위젯 + validator 기능
Form => 내부의 여러 위젯을 함께 그룹화하여 데이터 전송이 가능. 즉, 사용자로부터 입력을 받는 여러 위젯을 한번에 감싸서 손쉽게 데이터를 전송해줄 수 있음.
- hintText(미리 입력되어 있는 값)
- enabledBorder(기본 디자인)/ focusedBorder(터치시 디자인)/ errorBorder(에러 발생시 디자인/ focusedErrorBorder(에러 발생후 손가락 터치시 디자인)
주목할만한 점은 builder 위에 따로 상수로 정의한 _formKey 변수다. GlobalKey라는 객체를 넣어줬는데 이럴 Form에 연결하여 Form의 상태를 관리한다고 한다. 정확한 원리는 잘 모르겠다.
중간에, TextButton(onPressed:~)에서 실제 사용이 되는데 객체의 메소드를 통해서 폼 내부 위젯의 유효성 상태를 불러올 수 있는 것 같다. 즉 폼 내부에 있는 2개의 TextFormField 내부의 validator를 제어할 수 있는 듯 하다.
만약 특정 위젯의 디자인이 앱 내부에서 다 동일하다면 아래와 같이 지정해 손쉽게 디자인을 재사용할 수 있다고 한다.
구체적인 설명은 아님.
위 위젯은 Stack 방식으로 여러 위젯을 관리한다고 한다. 책이 탑처럼 쌓여있다면 가장 먼저 쌓은 책을 꺼내려면 맨 위에 있는 것부터 차례대로 꺼내야 하는 것이지.
첫번째 화면에서 push를 통해 세번째 화면으로 이동했다? 그럼 첫번째 화면으로 가기 위해선 2,3번째 화면을 Pop해서 버려줘야 한다는 것이당.
TextButton(
onPressed: () {
if (_formKey.currentState!.validate()) {
Navigator.pushNamed(context, "/home");
}
},
child: Text("Login"),
TextButton(
onPressed: () {
Navigator.pop(context);
},
child: Text("Get Started"),
뭐 이런 식으로 Push와 Pop을 사용한다. 인자로는 항상 context를 가져와줘야 하는 것 같다.