본문 바로가기
공허의 유산/사상의 도구

[Flutter]. 07. Flutter tutorial on codelab(3)

by 바른생활머시마 2023. 1. 23.
728x90
반응형

앞에서 앱의 가장 기본적인 구조, 즉, 화면과 로직을 구현하는 클래스를 정의하고 상호간 연동하는 부분을 구현하였습니다.

https://learn-and-give.tistory.com/44

 

[Flutter]. 05. Flutter tutorial on codelab(2)

지난 번에 버튼을 누르면 새로운 단어 쌍이 보여지는 샘플 앱을 만들었습니다. https://learn-and-give.tistory.com/40 [Flutter]. 04. Flutter tutorial on codelab(1) Flutter Learn에 소개 된 다음 내용은 codelab이라는 곳

learn-and-give.tistory.com

이번에는 외형을 기획 된 디자인에 맞게 수정을 해 보는 순서 입니다.

https://codelabs.developers.google.com/codelabs/flutter-codelab-first?hl=ko#4 

 

Your first Flutter app  |  Google Codelabs

In this codelab, you’ll learn how to build a Flutter app that generates random, cool-sounding names.

codelabs.developers.google.com

 

AS IS와 TO BE를 비교 해 보면서, 무엇을 하면 될지 대충 한번 감을 잡아보겠습니다.

먼저 크롬으로 띄운 AS IS는 아래와 같습니다.

Tutorial에 그려진 목표 형상은 아래와 같습니다.

눈에 띄는 수정 사항을 적어보면...

  • 불필요한 텍스트 삭제
  • 중앙 정렬
  • 텍스트 상자 설정(크기/배경색/라운드처리/폰트)
  • 버튼 색상 설정

일단 눈에 띄는 것은 이 정도로 보고, 이런 점을 감안해서 Tutorial을 따라 가 보겠습니다.

 

 

Refactoring

 

먼저, 화면에 보여질 wordpair를 조회 할 때 MyAppState에서 가져오는 부분이 Widget 설정부분에 묶여있어서 이를 State와 그 State의 data로 분리하는 수정을 하게 됩니다.아직은 이렇게 해야 할 이유를 딱히 모르겠습니다만, 일단 데이터를 설정하는 부분에서는 변경 될 여지가 있는 참조를 두지 않는 것을 지향한다 정도로 Refactoring을 하기 위한 준비라고 보면 될 것 같습니다.

 이를 위해 Text 설정 부분의 MyAppState 참조 부분을 밖으로 꺼내고, 거기서 읽은 데이터를 변수에 담아 설정하도록 수정합니다.

 

이렇게 되어 있던 코드를...

class MyHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    var appState = context.watch<MyAppState>();

    return Scaffold(
      body: Column(
        children: [
          Text('A random AWESOME idea:'),
          Text(appState.current.asLowerCase), //<--------

이렇게 수정합니다.

class MyHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    var appState = context.watch<MyAppState>();
    var pair = appState.current; //<---

    return Scaffold(
      body: Column(
        children: [
          Text('A random AWESOME idea:'),
          Text(pair.asLowerCase),  //<---

Hot reload를 통해 수정한 내용에 이상이 없는지 바로 확인 해 볼 수 있습니다.

 

다음으로 실제 Refactoring을 하는 과정인데, Text로 표시하는 부분을 다른 클래스를 사용해서 표시하도록 합니다. 이때 다른 클래스는 따로 정의해서 사용 할 수도 있는데, Refactoring을 할 때 직접 정의한 클래스를 써서 처리하는 과정을 보여주는 예제라고 보면 될 것 같습니다.

 

먼저, 두번째 Text Widget을 선택한 상태에서 마우스 오른쪽 버튼을 눌러 context menu를 띄우고, 거기서 Refactor를 선택합니다.

매뉴에서 Extract Widget을 선택하고, 입력창에서 Widget 이름을 BigCard라고 입력합니다.

이렇게 하고 나면, Text Widget이 BigCard라는 클래스로 변경되고, 코드 가장 아래쪽에 BigCard라는 클래스가 추가 됩니다. BigCard가 원래 제공되는 클래스인지 정확히 모르겠네요. build 함수의 리턴값으로 Text Widget을 넘겨주고 있으니 아마도 그대로 실행해도 똑같이 될 것 같은데, 멤버로 WordPair가 있는 것을 보면 원래부터 있는 것 같기도 하고... 저장을 하고(Hot reload가 되고) 보니 이전처럼 보이는 것으로 봐서 기존의 Widget을 리턴 해 주되 다른 처리를 할 수 있는 형태로 변경하는 과정인 것 같습니다. 아직은 배경 지식이 부족하니 너무 고민하지 말고 일단 한번 따라가 보는데 의의를 두고 진행 해 보겠습니다.

 

 

 

Add a Card

 다음으로 실제 카드처럼 만드는 과정인데, Flutter에서 Widget을 다룰 때는 어떤 Widget을 다른 곳에 포함 시켜서 영향을 받도록 하는 과정이 많기 때문인지, Wrap... 과 같은 유형의 Context menu가 많이 보였습니다. 저 BigCard가 리턴해주는 Text를 그대로 리턴하지 않고, Card 모양으로 만들기 위한 처리를 추가 해 볼텐데, 이를 위해 Text 주변에 여백(Padding)을 추가 해 보겠습니다. 이를 위해 Padding 위젯 속으로 Text 위젯을 넣어야 하는데, 이를 간단히 해주는 context menu가 바로 Wrap with Padding입니다. 앞에서 이미 한번 해 보았던 Refactor를 한 후, 그 다음에 나오는 매뉴에서 선택 가능합니다.

이 명령을 적용하면 코드가 아래와 같이 변경 됩니다.

class BigCard extends StatelessWidget {
  const BigCard({
    Key? key,
    required this.pair,
  }) : super(key: key);

  final WordPair pair;

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.all(8.0),
      child: Text(pair.asLowerCase),
    );
  }
}

기존 Text위젯은 그대로 있고, 그 주변에 여백을 설정 할 수 있게 되었네요. all(8)이라고 된 것을 보니 모든 방향의 여백을 8로 지정하는 코드 같습니다. 이 값을 30으로 크게 변경하니 주변 여백이 늘어나는 것을 볼 수 있습니다. 여백은 tutorial의 내용처럼  20으로 해두겠습니다.

어떤 특성을 부여 하게 될 때 이런 방식으로 Wrap을 써서 처리를 많이 하게 되는 것 같습니다.

다음으로 여백이 생긴 이 전체를 '카드' 위젯으로 만들기 위해, Padding을 Card위젯으로 싸도록 하겠습니다. 방식은 동일합니다.(Refactor 매뉴는 단축키 Control+Shift+R) Card라는 위젯이 목록에 보이지 않으므로, widget으로 해두고 직접 Card라고 입력합니다. 자주쓰는 위젯들만 목록에 있는 것 아닌가 싶네요.

Card라는 Widget이 지원되는 위젯이 맞는지, 이렇게만 설정해줘도 카드가 나타나내요.

BigCard와 Text를 다 한꺼번에 묶어서 중앙정렬 하는 위젯을 적용시키면 될 것 같네요.

 

Theme and style

테마와 스타일을 적용하는 부분입니다. 앱을 개발하다보면 구글이나 애플의 디자인 가이드라인에 대한 이야기를 듣게 되는데, 개발자가 일일이 다 직접 맞춰주는 것은 매우 어려운 과정일 것 입니다. 그래서, 이렇게 테마/스타일을 제공해주고 필요한 변경만 직접 수정해서 하도록 하면 동일 된 UX라서 사용자들도 쓰기 편리 할 것 같습니다.

 

아래와 같은 두 줄을 추가 합니다.

 테마를 사용하겠다, 그리고, 테마의 primary 색상을 카드에 적용하겠다... 이 정도 내용이겠네요.

  @override
  Widget build(BuildContext context) {
    var theme = Theme.of(context);         // ← Add this.

    return Card(
      color: theme.colorScheme.primary,    // ← And also this.
      child: Padding(
        padding: const EdgeInsets.all(20.0),
        child: Text(pair.asLowerCase),
      ),
    );
  }

이렇게 적용하면 아래와 같이 카드 색상이 변경 됩니다. 이 색상은 MyApp 구현 내용 중, Colorscheme에 정의 된 색상의 영향을 받으며, Seed Color를 설정하면 이 색상을 이용해서 테마 색상들을 만들어 내는 것 같네요. Tutorial에는 색상을 변경하면 부드럽게 animation 되면서 변경 된다는데, 코드를 수정해서 저장하면 animation은 되지 않고 그냥 리로드 되면서 변경되네요.(테스트 환경이 크롬이라서 그럴지도...)

 

 

실제로 겉 모습이 많이 달라진 것은 없지만, 어떤 방식으로 스타일을 만들어 나가는지에 대해서는 두루 훑어본 것 같습니다.  너무 많이 하면 지치니까 요기에서 한번 끊고, 다음에 이어서 텍스트 스타일과 정렬 등을 살펴보겠습니다.

https://learn-and-give.tistory.com/47

 

[Flutter]. 07. Flutter tutorial on codelab(4)

앞에서 UI를 재정의 하는 코드를 삽입하는 방법과 Refactoring 명령으로 Wrapping 하는 방법 등을 살펴보았습니다. https://learn-and-give.tistory.com/46 [Flutter]. 06. Flutter tutorial on codelab(3) 앞에서 앱의 가장 기

learn-and-give.tistory.com

 

728x90
반응형

댓글