ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • UI Development Exam - Widget 너비 조정, Child Widget 데이터 전달, Custom Font 사용
    DEVELOPMENT/FLUTTER 2022. 1. 20. 21:39

    저에겐 HTML5 등 웹프로그래밍 언어 학습 시 알고리즘보다 화면 표시 과정 상에서 어려움을 겪는 일이 많았습니다. 저는 보통 기능 구상 후 화면 속 컴포넌트를 배치하고 난 후 이에 따라 프로그래밍을 하게 되는데, 화면 구성이 다 끝나지 않으면 다음 단계로 진도가 나아가지 않더라구요. 그렇다고 딱히 제가 생업으로 프로그래밍을 하는 것이 아니기 때문에 틈날 때 짬을 내어 하는 것이라 시간을 많이 투자할 수도 없었고 물어 볼 누군가도 없었습니다.

    그래서 그런지 지금도 HTML5와 CSS는 저에겐 굉장히 낯선 프로그래밍 언어입니다.

    PyQT5나 Android, Flex, Adobe Animate가 그래서 더 익숙하고 애착이 가더라구요.

     

    Widget 너비 조정(100%)

     

    Flutter 위젯 배치는 쉬운 것 같으면서도 어려운 것 같습니다. 폭(너비)을 설정할 수 있는 위젯과 그렇지 않은 위젯이 있고,  Child 위젯에 맞게 Parent 위젯이 크기가 변경되는 위젯도 있기 때문에 Child 위젯을 배치하고 나서 원하는 UI 모습이 안 나오는 경우도 있어 헷갈립니다.

    이 때문에 약간 스트레스를 받다가 생각한 점은 필요한 경우 Container 위젯으로 다른 위젯을 감싸면 되지 않을까 하는 점이었습니다. Container 위젯은 Width를 설정할 수 있으니 편합니다. 어떤 위젯으로 감싸야하는지.. 너비를 가진 위젯은 무엇인지 고민을 안 해도 되고...

    단, Container 위젯이 너무 많아지는 느낌을 받게 된다는... 코드가 지저분해지는 느낌??

     

    width: double.infinity, // Device의 너비로 강제 설정, 100%

     

    실제 사용한 코드는 아래와 같습니다.

     

    import 'package:flutter/cupertino.dart';
    
    import 'my_menu_circle.dart';
    import 'package:flutter/material.dart';
    
    class MyMenu extends StatefulWidget {
      const MyMenu({Key? key}) : super(key: key);
    
      @override
      _MyMenuState createState() => _MyMenuState();
    }
    
    class _MyMenuState extends State<MyMenu> {
      @override
      Widget build(BuildContext context) {
        return Container(
          width: double.infinity, // 너비 100%
          child: Padding(
            padding: EdgeInsets.all(10),
            child: Row(
              mainAxisAlignment: MainAxisAlignment.spaceAround,
              children: [
                MyCirlceMenu(Icons.food_bank, "ALL"),
                MyCirlceMenu(Icons.emoji_food_beverage, "Coffee"),
                MyCirlceMenu(Icons.fastfood, "Burger"),
                MyCirlceMenu(Icons.local_pizza, "Pizza"),
              ],
            )
          )
        );
      }
    }

     

    Container 위젯은 Child Widget이 없는 경우에는 최대한 많은 폭을 차지하도록 설정되어 있으나, Child Widget이 있으면 해당 위젯을 감쌀 수 있는 최소한의 크기로 자동 변환되어 너비가 갑자기 줄어든 것처럼 보입니다. 당연히 크기가 줄어들어 Widget 배치가 다 틀어지게 되죠.

    전 Container 위젯이 화면 너비를 꽉 차게 표현하고 싶었기 때문에 컨테이너의 너비를 100% 로 강제하도록 프로그래밍했습니다.

     

    Widget으로의 데이터 전달

     

    페이지 간 데이터 전달이 아닌 동일한 페이지 내의 위젯으로 데이터를 전달해야 하는 경우가 많습니다. 동일한 코드 내에서 동일한 변수를 참조할 수 있다면 굳이 신경을 쓸 필요가 없지만, 위젯을 개별 클래스로 각각 구현하는 경우에는 데이터를 다른 클래스로 데이터를 전달하는 코드를 작성해야 합니다.

     

     

    특히 위의 그림과 같이 동일한 UI 화면구성을 가지며 아이콘과 텍스트만 다른 위젯을 만들 때에는 코드의 재사용을 위해 반드시 해야 할 작업입니다.

     

    import 'package:flutter/cupertino.dart';
    import 'package:flutter/material.dart';
    
    class MyCirlceMenu extends StatefulWidget {
      final IconData myicon; // 받은 데이터를 저장하는 변수 1
      final String mymenu; // 받은 데이터를 저장하는 변수 2
    
      const MyCirlceMenu(this.myicon, this.mymenu); // 데이터 전달을 특정하는 생성자
    
      @override
      _MyCirlceMenuState createState() => _MyCirlceMenuState();
    }
    
    class _MyCirlceMenuState extends State<MyCirlceMenu> {
      @override
      Widget build(BuildContext context) {
        return Container(
          width: 60,
          height: 60,
          decoration: BoxDecoration(
            shape: BoxShape.circle,
            color: Colors.white,
            border: Border.all(color: Colors.black26)
          ),
          child: Center(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget> [
                Icon(widget.myicon, color: Colors.red), // 전달받은 데이터는 widget.변수명으로 접근함
                Text(widget.mymenu, style: TextStyle(fontFamily: 'kpbm'),)
              ]
            ),
          )
        );
      }
    }

     

    MyCircleMenu 클래스에 final 변수를 2개 추가했으며, 생성자로 해당 변수에 저장할 값을 강제해 놓았습니다.  이렇게 전달받은 변수는 실제 위젯 작성 클래스(여기서는 _MyCirlceMenuState 클래스)에서 widget.변수명으로 접근할 수 있습니다.

     

    Custom Font

     

    애플리케이션의 정체성과 UI가 주는 고유의 느낌은 해당 애플리케이션에서 사용하는 이미지와 폰트를 통해서도 나타낼 수 있습니다.

    시스템 폰트가 아닌 애플리케이션만의 폰트를 사용하려면 다음과 같이 폰트를 임베딩하면 됩니다.

     

    우선 폰트를 다운로드해야겠죠? 폰트 라이선스를 확인한 후 사용 허가가 된 폰트 파일을 프로젝트 폴더에 붙여넣습니다. 저는 문화체육관광부에서 제작한 KoPubWorldBatangMedium 서체를 사용했습니다.

     

     

    위의 작업을 완료했다면 'pubspec.yaml' 파일을 열어 아래와 같이 붙여넣기한 폰트의 정보를 입력합니다. 폰트 정보는 yaml 파일의 최하단에 위치합니다.

    name: my_recipe_app
    description: A new Flutter project.
    
    # The following line prevents the package from being accidentally published to
    # pub.dev using `flutter pub publish`. This is preferred for private packages.
    publish_to: 'none' # Remove this line if you wish to publish to pub.dev
    
    # The following defines the version and build number for your application.
    # A version number is three numbers separated by dots, like 1.2.43
    # followed by an optional build number separated by a +.
    # Both the version and the builder number may be overridden in flutter
    # build by specifying --build-name and --build-number, respectively.
    # In Android, build-name is used as versionName while build-number used as versionCode.
    # Read more about Android versioning at https://developer.android.com/studio/publish/versioning
    # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
    # Read more about iOS versioning at
    # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
    version: 1.0.0+1
    
    environment:
      sdk: ">=2.15.1 <3.0.0"
    
    # Dependencies specify other packages that your package needs in order to work.
    # To automatically upgrade your package dependencies to the latest versions
    # consider running `flutter pub upgrade --major-versions`. Alternatively,
    # dependencies can be manually updated by changing the version numbers below to
    # the latest version available on pub.dev. To see which dependencies have newer
    # versions available, run `flutter pub outdated`.
    dependencies:
      flutter:
        sdk: flutter
    
    
      # The following adds the Cupertino Icons font to your application.
      # Use with the CupertinoIcons class for iOS style icons.
      cupertino_icons: ^1.0.2
    
    dev_dependencies:
      flutter_test:
        sdk: flutter
    
      # The "flutter_lints" package below contains a set of recommended lints to
      # encourage good coding practices. The lint set provided by the package is
      # activated in the `analysis_options.yaml` file located at the root of your
      # package. See that file for information about deactivating specific lint
      # rules and activating additional ones.
      flutter_lints: ^1.0.0
    
    # For information on the generic Dart part of this file, see the
    # following page: https://dart.dev/tools/pub/pubspec
    
    # The following section is specific to Flutter.
    flutter:
    
      # The following line ensures that the Material Icons font is
      # included with your application, so that you can use the icons in
      # the material Icons class.
      uses-material-design: true
    
      # To add assets to your application, add an assets section, like this:
      assets:
        - images/
    
      # An image asset can refer to one or more resolution-specific "variants", see
      # https://flutter.dev/assets-and-images/#resolution-aware.
    
      # For details regarding adding assets from package dependencies, see
      # https://flutter.dev/assets-and-images/#from-packages
    
      # To add custom fonts to your application, add a fonts section here,
      # in this "flutter" section. Each entry in this list should have a
      # "family" key with the font family name, and a "fonts" key with a
      # list giving the asset and other descriptors for the font. For
      # example:
      fonts:
        - family: kpbm
          fonts:
            - asset: fonts/kpbm.ttf
      #       - asset: fonts/Schyler-Italic.ttf
      #         style: italic
      #   - family: Trajan Pro
      #     fonts:
      #       - asset: fonts/TrajanPro.ttf
      #       - asset: fonts/TrajanPro_Bold.ttf
      #         weight: 700
      #
      # For details regarding fonts from package dependencies,
      # see https://flutter.dev/custom-fonts/#from-packages

     

    이제 아래의 코드와 같이 폰트가 사용될 Text 위젯의 스타일 속성에서 임베딩한 폰트를 사용하면 됩니다.

     

    Text(widget.mymenu, style: TextStyle(fontFamily: 'kpbm'),)

     

    출처: pixnio.com

     

    Free picture: programming, code, programmer, coding, coffee cup, computer, copy, hands, computer keyboard

    Free photo: programming, code, programmer, coding, coffee cup, computer, copy, hands, computer keyboard.

    pixnio.com

     

    이런 삶을 꿈꾸었으나 현실은.. 버벅버벅...

Designed by Tistory.