[flutter (플루터 앱 개발)] How to Implement Any UI in Flutter : 플러터에서 모든 UI를 구현하는 방법

 

 

How to Implement Any UI in Flutter

In this article, you will learn how to convert any user interface image, piece, or screen into Flutter code.

This is not a tutorial on building an app. It is rather a guide that will help you implement any UI you come across into an app you already have. This tutorial also explains a wide variety of UI concepts in Flutter.

Table of Contents

What is Flutter?

Flutter is an open source framework by Google for building beautiful, natively compiled, multi-platform applications from a single codebase. – (source: flutter.dev)

In Flutter, contrary to most frameworks, Dart is the only programming language you use to code. This is an underemphasized benefit of Flutter. Especially for a tool that can build desktop, mobile, and web applications.

Most UI platforms use more than one language. For example, in front-end web development, you have to write HTMLCSS, and JavaScript. For Android, you have to write Kotlin (or Java) and XML. But in Flutter, it's just one language: Dart.

Coupled with the only-one-programming-language benefit, Flutter is simple because everything in Flutter is a widget. For example [AnimatedWidget](https://api.flutter.dev/flutter/widgets/AnimatedWidget-class.html)[BottomNavigationBar](https://api.flutter.dev/flutter/material/BottomNavigationBar-class.html)[Container](https://api.flutter.dev/flutter/widgets/Container-class.html)[Drawer](https://api.flutter.dev/flutter/material/Drawer-class.html)[ElevatedButton](https://api.flutter.dev/flutter/material/ElevatedButton-class.html)[FormField](https://api.flutter.dev/flutter/widgets/FormField-class.html)[Image](https://api.flutter.dev/flutter/widgets/Image-class.html)[Opacity](https://api.flutter.dev/flutter/widgets/Opacity-class.html)[Padding](https://api.flutter.dev/flutter/widgets/Padding-class.html), ...

This is part of what makes Flutter easy to use – it's basically plain English. Widget names reflect what they are and their properties are easy to understand.

Widgets in Flutter

A widget is a Dart class that either extends StatefulWidget or StatelessWidget.

Your local Flutter installation comes with several widgets. To check out the widgets available by default, open the packages folder of your Flutter installation in your preferred editor. Then search across all files for "extends StatefulWidget" and "extends StatelessWidget" and take note of the number of results.

Image

As of Flutter 2.10, you will get 408 StatefulWidgets and 272 StatelessWidgets. That is a total of 680 widgets available for you to use and implement UIs.

These widgets typically have all you need. But at times they may not be enough. pub.dev, Dart and Flutter's package manager, have many more widgets you can use to implement UIs.

It is difficult to count the widgets in pub.dev. But searching an empty string (don't enter anything in the search bar and then press the search icon) and setting the SDK to Flutter returns the current total number of published packages.

Image

At the time of writing, there are more than 23000 Flutter packages in pub.dev. Each package has at least one widget. This means that you have more than 23000 widgets from pub.dev to implement, in addition to the available 680. This means that you can really implement any UI you want easily in Flutter.

Adding to the many available widgets, you can also create your own widgets as you implement UIs.

The Widget Tree

The following is part of the code you get when you create a new Flutter project and remove the comments:

 
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            const Text(
              'You have pushed the button this many times:',
            ),
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.headline4,
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: const Icon(Icons.add),
      ),
    );
  }

The parent Scaffold takes the appBarbody, and floatingActionButton parameters. In turn, the [AppBar](https://api.flutter.dev/flutter/material/AppBar-class.html) also takes a title parameter that has a Text value.

body takes a Center value that has a Column child. The Column in turn has two Texts as children. The FloatingActionButton takes the onPressed callback, 'Increment' tooltip, and an Icon for a child.

ImageFlutter widget tree breakdown

This is a simple widget tree. It has parents and descendants. child and children are common properties of most Flutter widgets. As widgets continuously take more widget children, your app gradually grows into a large widget tree.

As you implement UIs in Flutter, bear in mind that you are building a widget tree. You will notice that your code indents inwards from the left margin. It seems to develop some kind of virtual greater than sign (of empty space) at the left.

Note: Huge indentation levels are a sign that you need to refactor your code. It means that you need to extract some widget hierarchy into a separate widget.

How to Implement Any UI in Flutter

1. Write your code starting at the top left and move down to the bottom right

You'll implement the UI widget after widget according to each element's position in the UI. So you will first write code for things that appear at the top of the UI. Then you keep writing code for the other items moving down the page until you reach the bottom of that UI.

Image

This is intuitive.

On the horizontal axis, go from left to right. If need be, or if it is a right-to-left UI, then implement it from right to left instead.

2. Choose a Widget

Next you'll need to logically determine the widget you want to use for a given UI element. At a bare minimum, for a given UI element, you will use simple widgets you're familiar with based on what their names say they do.

Chances are the name of what the UI component looks like is the name of the widget. If you find it hard to make a choice, a quick online search will give you the answers. Flutter has a great online community.

3. Use widget groups

If a group of UI items is arranged vertically, one after another, use a [Column](https://api.flutter.dev/flutter/widgets/Column-class.html). If they are arranged horizontally, one after another, use a [Row](https://api.flutter.dev/flutter/widgets/Row-class.html). If they are placed on top of each other, use a [Stack](https://api.flutter.dev/flutter/widgets/Stack-class.html), with the floating widgets wrapped in [Positioned](https://api.flutter.dev/flutter/widgets/Positioned-class.html) widgets.

a. Column/Row

Inside a Column or Row, you can change or adjust how the widgets will align themselves on the main or cross axis. Use their [CrossAxisAlignment](https://api.flutter.dev/flutter/rendering/CrossAxisAlignment.html) and [MainAxisAlignment](https://api.flutter.dev/flutter/rendering/MainAxisAlignment.html) properties for such adjustments.

For the cross axis, you can align to center, end, start, and stretch. For the main axis, you can align to center, end, space around, space between, space evenly, and end.

In a Column, the vertical axis is the main axis while the horizontal axis is the cross axis. In a Row, the horizontal axis is the main axis while the vertical axis is the cross axis.

ImageAdapted from https://arzerin.com/2019/11/20/flutter-column/

ImageAdapted from https://arzerin.com/2019/11/20/flutter-row/

In Columns and Rows, if you want a particular child widget to take as much available space as possible, wrap that widget inside an [Expanded](https://api.flutter.dev/flutter/widgets/Expanded-class.html) widget. If you are familiar with web frontend, you'll notice that Columns and Rows are like [display: flex;](https://developer.mozilla.org/en-US/docs/Web/CSS/flex) in CSS.

b. Stack Widget

With Stack, the last widget(s) in the children's list appears on top of the earlier children.

You might have to edit the Stack's [alignment](https://api.flutter.dev/flutter/widgets/Stack/alignment.html) to indicate the relative positions of the widgets. Like [topCenter](https://api.flutter.dev/flutter/painting/AlignmentDirectional/topCenter-constant.html)[center](https://api.flutter.dev/flutter/painting/AlignmentDirectional/center-constant.html)[bottomEnd](https://api.flutter.dev/flutter/painting/AlignmentDirectional/bottomEnd-constant.html), and so on.

The Stack's size is calculated based on non-positioned widgets (Widgets in the children list not wrapped in a [Positioned](https://api.flutter.dev/flutter/widgets/Positioned-class.html) parent). When coding, remember that your Stack should either have at least one non-positioned widget, or it should be wrapped in a parent widget that explicitly sets the Stack's size.

Positioned takes any or all of [bottom](https://api.flutter.dev/flutter/widgets/Positioned/bottom.html)[top](https://api.flutter.dev/flutter/widgets/Positioned/top.html)[left](https://api.flutter.dev/flutter/widgets/Positioned/left.html)[right](https://api.flutter.dev/flutter/widgets/Positioned/right.html). They set the child's position relative to the Stack. Negative values move the child in the opposite direction. However, negative values clip parts of the child out. Use [clipBehavior: Clip.none](https://api.flutter.dev/flutter/widgets/Stack/clipBehavior.html) on the Stack to show all the parts of the positioned widget.

ImageFull code here.

4. Create custom widgets

As you build the widget tree, you will notice two things:

  1. Either a chunk of the tree grows too big and it is a logical unit on its own.
  2. Or some chunks or sets of widgets might repeat themselves with slight changes.

These are two indications that you should refactor your code. It means that you should extract out those widgets and define them in another Dart file.

Your code editor will help you with refactoring. With or without the editor, all you need to do is:

  1. Create a new Dart file. The file name should reflect the new widget's name.
  2. Create a new class that extends StatefulWidget or StatelessWidget, depending on if the new widget has State or not.
  3. Then return the widget chunk from a [build](https://api.flutter.dev/flutter/widgets/StatelessWidget/build.html) method.
  4. (Optional) If need be, your new Dart class can take positional or named parameters to its constructor to customize the widget's look.
// in counter_display.dart
import 'package:flutter/material.dart';

class CounterDisplay extends StatelessWidget {
  
  Widget build(BuildContext context) {
    return Column(
        mainAxisAlignment: MainAxisAlignment.center,
      children: [
        Text('You have pushed the button this many times:'),
        Text('$counter', style: TextStyle(fontSize: 24)),
      ],
    );
  }
}

// in main.dart
//
// ... 
  body: Center(child: CounterDisplay()),
// ...

You will build many custom widgets and they in turn will be descendants to more custom widgets, and that's fine. The widget tree is meant to continuously grow as the need arises.

5. Add more customization

You won't customize widgets only because of refactoring and repetitions (DRY code). You will create custom widgets because of the UI you are implementing.

You will create custom widgets because the many available widgets don't always meet the exact needs of a given UI. You'll need to combine them in some special way to implement a particular UI.

a. Container Widget

[Container](https://api.flutter.dev/flutter/widgets/Container-class.html) is a powerful widget. You can style it in different ways. If you are used to web frontend, you'll notice that it is like a [div](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/div) in HTML.

Container is a base widget. You can use it to create any UI piece.

Some Container parameters are [constraints](https://api.flutter.dev/flutter/widgets/Container/constraints.html)[decoration](https://api.flutter.dev/flutter/widgets/Container/decoration.html)[margin](https://api.flutter.dev/flutter/widgets/Container/margin.html)[padding](https://api.flutter.dev/flutter/widgets/Container/padding.html)[transform](https://api.flutter.dev/flutter/widgets/Container/transform.html), among others. Of course, Container takes a [child](https://api.flutter.dev/flutter/widgets/Container/child.html) which can be any widget.

The decoration property can take a [BoxDecoration](https://api.flutter.dev/flutter/painting/BoxDecoration-class.html), which in turn can take several other properties. This is the heart of Container's flexibility. BoxDecoration takes parameters like [border](https://api.flutter.dev/flutter/painting/BoxDecoration/border.html)[borderRadius](https://api.flutter.dev/flutter/painting/BoxDecoration/borderRadius.html)[boxShadow](https://api.flutter.dev/flutter/painting/BoxDecoration/boxShadow.html)[color](https://api.flutter.dev/flutter/painting/BoxDecoration/color.html)[gradient](https://api.flutter.dev/flutter/painting/BoxDecoration/gradient.html)[image](https://api.flutter.dev/flutter/painting/BoxDecoration/image.html)[shape](https://api.flutter.dev/flutter/painting/BoxDecoration/shape.html), among others.

With these parameters and their values, you can implement any UI to your taste. You can use Container instead of the many material widgets that Flutter comes with. That way your app is to your taste.

b. GestureDetector / InkWell

[GestureDetector](https://api.flutter.dev/flutter/widgets/GestureDetector-class.html) as the name implies detects user interactions. Not every UI piece is a button. And while implementing UIs you will need some widgets to react to user actions. In such a case, use GestureDetector.

GestureDetector can detect different types of gestures: taps, double taps, swipes, ... GestureDetector of course takes a [child](https://api.flutter.dev/flutter/widgets/GestureDetector/child.html) (which can be any widget), and different callbacks for different gestures like [onTap](https://api.flutter.dev/flutter/widgets/GestureDetector/onTap.html)[onDoubleTap](https://api.flutter.dev/flutter/widgets/GestureDetector/onDoubleTap.html)[onPanUpdate](https://api.flutter.dev/flutter/widgets/GestureDetector/onDoubleTap.html) (for swipes), ...

Note: By default, when users interact with the empty spaces in the child of GestureDetectors, the callbacks are not called. If you want your GestureDetector to react to gestures on empty space (within its child), then set the [behavior](https://api.flutter.dev/flutter/widgets/GestureDetector/behavior.html) property of the GestureDetector to [HitTestBehavior.translucent](https://api.flutter.dev/flutter/rendering/HitTestBehavior.html).

GestureDetector(
  // set behavior to detect taps on empty spaces
  behavior: HitTestBehavior.translucent,
  child: Column(
    children: [
      Text('I have space after me ...'),
      SizedBox(height: 32),
      Text('... that can detect taps.'),
    ],
  ),
  onTap: () => print('Tapped on empty space.'),
)

[InkWell](https://api.flutter.dev/flutter/material/InkWell-class.html) is similar to GestureDetector. It responds to some gestures that GestureDetector responds to. However, it shows ripple effects when interacted with (which GestureDetectors don't).

ImageFrom https://stackoverflow.com/q/58285012/13644299

InkWell must have a [Material](https://api.flutter.dev/flutter/material/Material-class.html) ancestor. So, if your topmost widget is [MaterialApp](https://api.flutter.dev/flutter/material/MaterialApp-class.html) you need not worry. Else, wrap the InkWell in a Material.

You should also do this wrapping if you are changing the colors of the InkWell's parent or child. If you don't, the ripple won't show. You also have to set the [color](https://api.flutter.dev/flutter/material/Material/color.html) of the Material widget for the ripple to show. You can set the color to [Colors.transparent](https://api.flutter.dev/flutter/material/Colors/transparent-constant.html) and Flutter will take care of the rest.

How to Implement Scrolling Interfaces

Scrolling is a little delicate topic. By default, widgets don't scroll in Flutter. If your Column or Row will be scrollable, use a [ListView](https://api.flutter.dev/flutter/widgets/ListView-class.html) instead. ListView takes children parameter too.

ListView also has factory constructors like [ListView.builder](https://api.flutter.dev/flutter/widgets/ListView/ListView.builder.html) and [ListView.separated](https://api.flutter.dev/flutter/widgets/ListView/ListView.separated.html). The builder gives you more control over the build process of the children whereas the separated takes into account a Separator (like [Divider](https://api.flutter.dev/flutter/material/Divider-class.html) for example).

By default, ListViews scroll their children vertically. However, you can change the [scrollDirection](https://api.flutter.dev/flutter/widgets/ScrollView/scrollDirection.html) of a ListView to [Axis.horizontal](https://api.flutter.dev/flutter/painting/Axis.html) to scroll its children horizontally.

At times, you might want to use [SingleChildScrollView](https://api.flutter.dev/flutter/widgets/SingleChildScrollView-class.html) instead of ListView. As the name implies, it takes a single [child](https://api.flutter.dev/flutter/widgets/SingleChildScrollView/child.html) and it can scroll. You can pass widget groups as its child.

There are other scrolling widgets.

But take special note of [CustomScrollView](https://api.flutter.dev/flutter/widgets/CustomScrollView-class.html). It gives you huge control of scrolling, unlike the others. It takes [slivers](https://api.flutter.dev/flutter/widgets/CustomScrollView/slivers.html), which in turn are scrolling widgets with powerful scroll mechanisms.

[SliverFillRemaining](https://api.flutter.dev/flutter/widgets/SliverFillRemaining-class.html)[SliverFillViewport](https://api.flutter.dev/flutter/widgets/SliverFillViewport-class.html)[SliverGrid](https://api.flutter.dev/flutter/widgets/SliverGrid-class.html)[SliverList](https://api.flutter.dev/flutter/widgets/SliverList-class.html)[SliverPersistentHeader](https://api.flutter.dev/flutter/widgets/SliverPersistentHeader-class.html) among others, are examples of widgets you include in the list of slivers. Most of these widgets take a delegate, which handles how scrolling occurs.

A good case to use CustomScrollView is with [SliverAppBar](https://api.flutter.dev/flutter/material/SliverAppBar-class.html), where you want the AppBar to be expanded by default and shrunk on scroll.

Image

Another example could be with a [DraggableScrollableSheet](https://api.flutter.dev/flutter/widgets/DraggableScrollableSheet-class.html) where you keep some action button sticked to the bottom.

Image

About CustomPaint

This is where Flutter gave ultimate flexibility to the UI world.

[CustomPaint](https://api.flutter.dev/flutter/widgets/CustomPaint-class.html) is to Flutter what the _Canvas API_ is to HTML or SVG is to images.

CustomPaint is a widget in Flutter that gives you the ability to design and draw without limitations. It gives you a canvas on which you can draw with a [painter](https://api.flutter.dev/flutter/widgets/CustomPaint/painter.html).

ImageFrom https://blog.codemagic.io/flutter-custom-painter/

You will rarely use CustomPaint. But be aware that it exists. Because there might be very complex UIs that widget combinations might not implement them and you will have no choice than drawing with CustomPaint.

When that time comes, it won't be hard for you because you are already familiar with other widgets.

Summary

For a given UI piece, choose a widget, write its code, build the widget with other widgets, and see what great UI you are implementing with Flutter.

Implementing UIs is a major part of mobile, web, and desktop app development. Flutter is a UI toolkit that build cross-platform for those platforms. Flutter's declarative nature and its widget abundance make UI implementation simple.

Keep implementing UIs in Flutter. As you do, it will become second nature to you. And you will be able to implement any UI in Flutter.

[출처] https://www.freecodecamp.org/news/how-to-implement-any-ui-in-flutter/

 

플러터에서 모든 UI를 구현하는 방법

이 글에서는 사용자 인터페이스 이미지, 조각 또는 화면을 Flutter 코드 로 변환하는 방법을 알아봅니다 .

경축! 아무것도 안하여 에스천사게임즈가 새로운 모습으로 재오픈 하였습니다.
어린이용이며, 설치가 필요없는 브라우저 게임입니다.
https://s1004games.com

이것은 앱을 만드는 튜토리얼이 아닙니다. 오히려 여러분이 이미 가지고 있는 앱에 여러분이 마주치는 모든 UI를 구현하는 데 도움이 되는 가이드입니다. 이 튜토리얼은 또한 Flutter의 다양한 UI 개념을 설명합니다.

목차

플러터란 무엇인가?

Flutter는 단일 코드베이스에서 아름답고 네이티브 컴파일된 다중 플랫폼 애플리케이션을 구축하기 위한 Google의 오픈 소스 프레임워크입니다. – (출처 : flutter.dev )

Flutter에서는 대부분 프레임워크와 달리 Dart가 코딩에 사용하는 유일한 프로그래밍 언어입니다. 이는 Flutter의 과소평가된 이점입니다. 특히 데스크톱, 모바일 및 웹 애플리케이션을 빌드할 수 있는 도구의 경우 더욱 그렇습니다.

대부분 UI 플랫폼은 두 개 이상의 언어를 사용합니다. 예를 들어, 프런트엔드 웹 개발에서는 HTML , CSS , JavaScript를 작성해야 합니다 . Android 의 경우 Kotlin (또는 Java )과 XML을 작성해야 합니다 . 하지만 Flutter에서는 Dart라는 하나의 언어만 사용합니다.

단 하나의 프로그래밍 언어라는 이점과 더불어, Flutter는 모든 것이 위젯이기 때문에 간단합니다. 예를 들어 [AnimatedWidget](https://api.flutter.dev/flutter/widgets/AnimatedWidget-class.html)[BottomNavigationBar](https://api.flutter.dev/flutter/material/BottomNavigationBar-class.html)[Container](https://api.flutter.dev/flutter/widgets/Container-class.html)[Drawer](https://api.flutter.dev/flutter/material/Drawer-class.html)[ElevatedButton](https://api.flutter.dev/flutter/material/ElevatedButton-class.html)[FormField](https://api.flutter.dev/flutter/widgets/FormField-class.html)[Image](https://api.flutter.dev/flutter/widgets/Image-class.html)[Opacity](https://api.flutter.dev/flutter/widgets/Opacity-class.html)[Padding](https://api.flutter.dev/flutter/widgets/Padding-class.html), ...

이것이 Flutter를 사용하기 쉽게 만드는 부분입니다. 기본적으로 평범한 영어입니다. 위젯 이름은 위젯의 본질을 반영하며 속성은 이해하기 쉽습니다.

플러터의 위젯

위젯은 StatefulWidget 또는 StatelessWidget을 확장하는 Dart 클래스 입니다 .

로컬 Flutter 설치에는 여러 위젯이 제공됩니다. 기본적으로 사용 가능한 위젯을 확인하려면 선호하는 편집기에서 Flutter 설치의 패키지 폴더를 엽니다. 그런 다음 모든 파일에서 "extends StatefulWidget" 및 "extends StatelessWidget"을 검색하여 결과 수를 기록합니다.

영상

Flutter 2.10 부터 408개의 StatefulWidget과 272개의 StatelessWidget을 얻게 됩니다 . 즉, UI를 사용하고 구현할 수 있는 총 680개의 위젯이 제공됩니다.

이러한 위젯에는 일반적으로 필요한 모든 것이 있습니다. 하지만 때로는 충분하지 않을 수도 있습니다. Dart와 Flutter의 패키지 관리자인 pub.dev 에는 UI를 구현하는 데 사용할 수 있는 위젯이 훨씬 더 많이 있습니다.

pub.dev에서 위젯을 세는 것은 어렵습니다. 하지만 빈 문자열을 검색하고(검색창에 아무것도 입력하지 않고 검색 아이콘을 누르세요) SDK를 Flutter로 설정하면 현재 게시된 패키지의 총 수가 반환됩니다.

영상

이 글을 쓸 당시 pub.dev에는 23,000개가 넘는 Flutter 패키지가 있었습니다. 각 패키지에는 최소한 하나의 위젯이 있습니다. 즉, 사용 가능한 680개 외에도 pub.dev에서 구현해야 할 위젯이 23,000개가 넘습니다. 즉, Flutter에서 원하는 모든 UI를 쉽게 구현할 수 있습니다.

사용 가능한 위젯이 다양할 뿐만 아니라, UI를 구현하면서 나만의 위젯을 만들 수도 있습니다.

위젯 트리

다음은 새로운 Flutter 프로젝트를 생성하고 주석을 제거하면 생성되는 코드의 일부입니다.

 
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            const Text(
              'You have pushed the button this many times:',
            ),
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.headline4,
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: const Icon(Icons.add),
      ),
    );
  }

부모는 , 및 매개변수를 Scaffold취합니다 . 차례로 는 값이 있는 매개변수 도 취합니다 .appBarbodyfloatingActionButton[AppBar](https://api.flutter.dev/flutter/material/AppBar-class.html)titleText

bodyCenter는 . 를 갖는 값을 취합니다 Column child. 는 Column차례로 Text. 로 두 개의 s를 갖습니다 children. 는 콜백, 'Increment' 및 . 를 위한 . 를 FloatingActionButton취합니다 .onPressedtooltipIconchild

영상플러터 위젯 트리 분석

이것은 간단한 위젯 트리입니다. 부모와 자식이 있으며 대부분 Flutter 위젯의 공통 속성 child입니다 children. 위젯이 지속적으로 더 많은 위젯 자식을 가지면서 앱은 점차 큰 위젯 트리로 성장합니다.

Flutter에서 UI를 구현할 때 위젯 트리를 빌드하고 있다는 점을 명심하세요. 코드가 왼쪽 여백에서 안쪽으로 들여쓰기되는 것을 알 수 있습니다. 왼쪽에 일종의 가상 더 큰 기호(빈 공간)가 생기는 것 같습니다.

참고: 들여쓰기 수준이 크다면 코드를 리팩토링해야 한다는 신호입니다. 즉, 위젯 계층을 별도의 위젯으로 추출해야 한다는 뜻입니다.

플러터에서 모든 UI를 구현하는 방법

1. 왼쪽 상단에서 시작하여 오른쪽 하단으로 코드를 작성합니다.

UI에서 각 요소의 위치에 따라 UI 위젯을 하나씩 구현합니다. 따라서 먼저 UI 상단에 나타나는 항목에 대한 코드를 작성합니다. 그런 다음 해당 UI 하단에 도달할 때까지 페이지 아래로 이동하는 다른 항목에 대한 코드를 계속 작성합니다.

영상

이는 직관적입니다.

수평 축에서 왼쪽에서 오른쪽으로 가세요. 필요하다면, 또는 오른쪽에서 왼쪽으로 UI가 있다면, 대신 오른쪽에서 왼쪽으로 구현하세요.

2. 위젯 선택

다음으로 주어진 UI 요소에 사용할 위젯을 논리적으로 결정해야 합니다. 최소한 주어진 UI 요소에 대해 이름에서 알 수 있듯이 익숙한 간단한 위젯을 사용하게 됩니다.

UI 구성 요소의 이름은 위젯의 이름일 가능성이 큽니다. 선택하기 어렵다면 빠른 온라인 검색으로 답을 얻을 수 있습니다. Flutter에는 훌륭한 온라인 커뮤니티가 있습니다.

3. 위젯 그룹 사용

UI 항목 그룹이 수직으로 하나씩 배열되어 있는 경우 .을 사용합니다 [Column](https://api.flutter.dev/flutter/widgets/Column-class.html). 수평으로 하나씩 배열되어 있는 경우 .을 사용합니다 [Row](https://api.flutter.dev/flutter/widgets/Row-class.html). 서로 위에 배치되어 있는 경우 .을 사용 [Stack](https://api.flutter.dev/flutter/widgets/Stack-class.html)하고 떠다니는 위젯을 [Positioned](https://api.flutter.dev/flutter/widgets/Positioned-class.html)위젯으로 감쌉니다.

a. 열/행

Column또는 내부에서 Row위젯이 주축 또는 교차축에 어떻게 정렬되는지 변경하거나 조정할 수 있습니다. 이러한 조정에는 [CrossAxisAlignment](https://api.flutter.dev/flutter/rendering/CrossAxisAlignment.html)및 속성을 사용합니다.[MainAxisAlignment](https://api.flutter.dev/flutter/rendering/MainAxisAlignment.html)

교차 축의 경우, 중앙, 끝, 시작 및 늘림에 정렬할 수 있습니다. 주 축의 경우, 중앙, 끝, 주변 간격, 간격 사이, 균일한 간격 및 끝에 정렬할 수 있습니다.

a에서 Column수직축은 주축이고 수평축은 교차축입니다. a에서 Row수평축은 주축이고 수직축은 교차축입니다.

영상https://arzerin.com/2019/11/20/flutter-column/에서 발췌

영상https://arzerin.com/2019/11/20/flutter-row/에서 가져옴

Columns와 s 에서 Row특정 자식 위젯이 가능한 한 많은 사용 가능한 공간을 차지하도록 하려면 해당 위젯을 위젯 안에 래핑합니다 [Expanded](https://api.flutter.dev/flutter/widgets/Expanded-class.html). 웹 프런트엔드에 익숙하다면 Columns와 s가 CSS와 Row비슷하다는 것을 알 수 있을 것입니다.[display: flex;](https://developer.mozilla.org/en-US/docs/Web/CSS/flex)

b. 스택 위젯

를 사용하면 목록 Stack에 있는 마지막 위젯이 children이전 자식 위젯 위에 표시됩니다.

[alignment](https://api.flutter.dev/flutter/widgets/Stack/alignment.html)위젯의 상대적 위치를 나타내기 위해 Stack을 편집해야 할 수도 있습니다 . [topCenter](https://api.flutter.dev/flutter/painting/AlignmentDirectional/topCenter-constant.html)[center](https://api.flutter.dev/flutter/painting/AlignmentDirectional/center-constant.html)[bottomEnd](https://api.flutter.dev/flutter/painting/AlignmentDirectional/bottomEnd-constant.html), 등등.

'의 크기 Stack는 위치가 지정되지 않은 위젯(부모에 래핑되지 않은 자식 목록의 위젯 [Positioned](https://api.flutter.dev/flutter/widgets/Positioned-class.html))을 기준으로 계산됩니다. 코딩할 때는 Stack적어도 하나의 위치가 지정되지 않은 위젯이 있어야 하거나 '의 크기를 명시적으로 설정하는 부모 위젯에 래핑되어야 한다는 점을 기억하세요 Stack.

Positioned[bottom](https://api.flutter.dev/flutter/widgets/Positioned/bottom.html)[top](https://api.flutter.dev/flutter/widgets/Positioned/top.html)[left](https://api.flutter.dev/flutter/widgets/Positioned/left.html), . 중 하나 또는 전부를 취합니다 [right](https://api.flutter.dev/flutter/widgets/Positioned/right.html). 이들은 자식의 위치를 Stack​​. 에 상대적으로 설정합니다. 음수 값은 자식을 반대 방향으로 이동합니다. 그러나 음수 값은 자식의 일부를 잘라냅니다. [clipBehavior: Clip.none](https://api.flutter.dev/flutter/widgets/Stack/clipBehavior.html)에서 사용하여 Stack배치된 위젯의 모든 부분을 표시합니다.

영상전체 코드는 여기에서 확인하세요 .

4. 사용자 정의 위젯 만들기

위젯 트리를 구축하면 두 가지 사실이 눈에 띄게 됩니다.

  1. 나무의 한 덩어리가 너무 커져서 그 자체로 논리적인 단위가 되는 경우입니다.
  2. 또는 위젯의 일부 덩어리나 세트가 약간의 변경만으로 반복될 수도 있습니다.

이것들은 당신 이 코드를 리팩토링 해야 한다는 두 가지 표시입니다 . 즉, 당신은 그 위젯들을 추출하여 다른 Dart 파일에 정의해야 한다는 것을 의미합니다.

코드 편집기는 리팩토링에 도움이 됩니다. 편집기가 있든 없든, 해야 할 일은 다음과 같습니다.

  1. 새 Dart 파일을 만듭니다. 파일 이름은 새 위젯의 이름을 반영해야 합니다.
  2. 새 위젯에 State가 있는지 여부 에 따라 StatefulWidget 또는 StatelessWidget을 확장하는 새 클래스를 만듭니다 .
  3. 그런 다음 메서드에서 위젯 청크를 반환합니다 [build](https://api.flutter.dev/flutter/widgets/StatelessWidget/build.html).
  4. (선택 사항) 필요한 경우 새 Dart 클래스는 생성자에 위치 또는 명명된 매개변수를 가져와 위젯의 모양을 사용자 지정할 수 있습니다.
// in counter_display.dart
import 'package:flutter/material.dart';

class CounterDisplay extends StatelessWidget {
  
  Widget build(BuildContext context) {
    return Column(
        mainAxisAlignment: MainAxisAlignment.center,
      children: [
        Text('You have pushed the button this many times:'),
        Text('$counter', style: TextStyle(fontSize: 24)),
      ],
    );
  }
}

// in main.dart
//
// ... 
  body: Center(child: CounterDisplay()),
// ...

여러분은 많은 사용자 정의 위젯을 만들 것이고, 그것들은 차례로 더 많은 사용자 정의 위젯의 자손이 될 것입니다. 괜찮습니다. 위젯 트리는 필요에 따라 지속적으로 성장하도록 되어 있습니다.

5. 더 많은 사용자 정의 추가

리팩토링과 반복(DRY 코드) 때문에만 위젯을 사용자 정의하지 않을 것입니다 . 구현하는 UI 때문에 사용자 정의 위젯을 만들 것입니다.

사용 가능한 많은 위젯이 항상 주어진 UI의 정확한 요구를 충족하지 못하기 때문에 사용자 지정 위젯을 만들 것입니다. 특정 UI를 구현하려면 특별한 방식으로 위젯을 결합해야 합니다.

a. 컨테이너 위젯

[Container](https://api.flutter.dev/flutter/widgets/Container-class.html)강력한 위젯입니다. 다양한 방식으로 스타일을 지정할 수 있습니다. 웹 프런트엔드에 익숙하다면 [div](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/div)HTML과 비슷하다는 것을 알 수 있을 것입니다.

Container기본 위젯입니다. 이를 사용하여 모든 UI 조각을 만들 수 있습니다.

일부 Container매개변수는 [constraints](https://api.flutter.dev/flutter/widgets/Container/constraints.html)[decoration](https://api.flutter.dev/flutter/widgets/Container/decoration.html)[margin](https://api.flutter.dev/flutter/widgets/Container/margin.html)[padding](https://api.flutter.dev/flutter/widgets/Container/padding.html)[transform](https://api.flutter.dev/flutter/widgets/Container/transform.html), 등이 있습니다. 물론, 위젯이 될 수 있는 를 Container사용합니다 .[child](https://api.flutter.dev/flutter/widgets/Container/child.html)

속성 decoration은 를 취할 수 있으며 , 이는 다시 여러 다른 속성을 취할 수 있습니다. 이것이 '의 유연성 [BoxDecoration](https://api.flutter.dev/flutter/painting/BoxDecoration-class.html)의 핵심입니다 . , 등 의 매개변수를 취합니다 .ContainerBoxDecoration[border](https://api.flutter.dev/flutter/painting/BoxDecoration/border.html)[borderRadius](https://api.flutter.dev/flutter/painting/BoxDecoration/borderRadius.html)[boxShadow](https://api.flutter.dev/flutter/painting/BoxDecoration/boxShadow.html)[color](https://api.flutter.dev/flutter/painting/BoxDecoration/color.html)[gradient](https://api.flutter.dev/flutter/painting/BoxDecoration/gradient.html)[image](https://api.flutter.dev/flutter/painting/BoxDecoration/image.html)[shape](https://api.flutter.dev/flutter/painting/BoxDecoration/shape.html)

이러한 매개변수와 값을 사용하면 취향에 맞는 UI를 구현할 수 있습니다. Flutter가 제공하는 많은 소재 위젯Container 대신 사용할 수 있습니다 . 이렇게 하면 앱이 취향에 맞게 됩니다.

b. GestureDetector / InkWell

[GestureDetector](https://api.flutter.dev/flutter/widgets/GestureDetector-class.html)이름에서 알 수 있듯이 사용자 상호작용을 감지합니다. 모든 UI 조각이 버튼은 아닙니다. UI를 구현하는 동안 사용자 동작에 반응하는 위젯이 필요합니다. 그런 경우 GestureDetector.

GestureDetector탭, 두 번 탭, 스와이프 등 다양한 유형의 제스처를 감지할 수 있습니다. 물론 (모든 위젯이 될 수 있음)과 , GestureDetector[child](https://api.flutter.dev/flutter/widgets/GestureDetector/child.html)스와이프의 경우)와 같이 다양한 제스처에 대한 다양한 콜백을 [onTap](https://api.flutter.dev/flutter/widgets/GestureDetector/onTap.html)사용 합니다.[onDoubleTap](https://api.flutter.dev/flutter/widgets/GestureDetector/onDoubleTap.html)[onPanUpdate](https://api.flutter.dev/flutter/widgets/GestureDetector/onDoubleTap.html)

참고: 기본적으로 사용자가 s의 빈 공간과 상호 작용할 때 child콜백 GestureDetector은 호출되지 않습니다. 빈 공간( GestureDetector에서 제스처에 반응하도록 하려면 의 속성을 설정 합니다 .child[behavior](https://api.flutter.dev/flutter/widgets/GestureDetector/behavior.html)GestureDetector[HitTestBehavior.translucent](https://api.flutter.dev/flutter/rendering/HitTestBehavior.html)

GestureDetector(
  // set behavior to detect taps on empty spaces
  behavior: HitTestBehavior.translucent,
  child: Column(
    children: [
      Text('I have space after me ...'),
      SizedBox(height: 32),
      Text('... that can detect taps.'),
    ],
  ),
  onTap: () => print('Tapped on empty space.'),
)

[InkWell](https://api.flutter.dev/flutter/material/InkWell-class.html)와 유사합니다 GestureDetector일부 제스처 에 반응합니다. 그러나 상호 작용할 때 파장GestureDetector 효과가 나타납니다 ( s는 그렇지 않습니다).GestureDetector

영상https://stackoverflow.com/q/58285012/13644299에서

InkWell조상 이 있어야 합니다 [Material](https://api.flutter.dev/flutter/material/Material-class.html). 따라서 최상위 위젯이 있다면 [MaterialApp](https://api.flutter.dev/flutter/material/MaterialApp-class.html)걱정할 필요가 없습니다. 그렇지 InkWell않으면 Material.

InkWell's parent 또는 의 색상을 변경하는 경우에도 이 래핑을 수행해야 합니다 child. 그렇지 않으면 리플이 표시되지 않습니다. 리플을 표시하려면 위젯 [color](https://api.flutter.dev/flutter/material/Material/color.html)의 를 설정해야 합니다. 를 Material설정하면 Flutter가 나머지를 처리합니다.color[Colors.transparent](https://api.flutter.dev/flutter/material/Colors/transparent-constant.html)

스크롤링 인터페이스를 구현하는 방법

스크롤은 약간 민감한 주제입니다. 기본적으로 위젯은 Flutter에서 스크롤되지 않습니다. Column또는 가 Row스크롤 가능 하면 [ListView](https://api.flutter.dev/flutter/widgets/ListView-class.html)대신 를 사용합니다. 매개변수도 ListView사용합니다 .children

ListView[ListView.builder](https://api.flutter.dev/flutter/widgets/ListView/ListView.builder.html)또한 및 와 같은 팩토리 생성자가 있습니다 [ListView.separated](https://api.flutter.dev/flutter/widgets/ListView/ListView.separated.html). 는 builder자식의 빌드 프로세스를 더 많이 제어할 수 있는 반면 는 구분 기호 (예: 와 같은 ) separated를 고려합니다 .[Divider](https://api.flutter.dev/flutter/material/Divider-class.html)

기본적으로 ListViews는 자식을 수직으로 스크롤합니다. 그러나 [scrollDirection](https://api.flutter.dev/flutter/widgets/ScrollView/scrollDirection.html)a의 를 변경 ListView하여 [Axis.horizontal](https://api.flutter.dev/flutter/painting/Axis.html)자식을 수평으로 스크롤할 수 있습니다.

때때로 . [SingleChildScrollView](https://api.flutter.dev/flutter/widgets/SingleChildScrollView-class.html)대신 을 사용하고 싶을 수도 있습니다 ListView. 이름에서 알 수 있듯이, 단일을 사용 [child](https://api.flutter.dev/flutter/widgets/SingleChildScrollView/child.html)하고 스크롤할 수 있습니다. 위젯 그룹을 .으로 전달할 수 있습니다 child.

다른 스크롤링 위젯도 있습니다 .

하지만 특별히 에 유의하세요 [CustomScrollView](https://api.flutter.dev/flutter/widgets/CustomScrollView-class.html). 다른 것과 달리 스크롤을 엄청나게 제어할 수 있습니다. [slivers](https://api.flutter.dev/flutter/widgets/CustomScrollView/slivers.html), 이는 강력한 스크롤 메커니즘을 갖춘 스크롤 위젯입니다.

[SliverFillRemaining](https://api.flutter.dev/flutter/widgets/SliverFillRemaining-class.html)[SliverFillViewport](https://api.flutter.dev/flutter/widgets/SliverFillViewport-class.html)[SliverGrid](https://api.flutter.dev/flutter/widgets/SliverGrid-class.html)[SliverList](https://api.flutter.dev/flutter/widgets/SliverList-class.html)[SliverPersistentHeader](https://api.flutter.dev/flutter/widgets/SliverPersistentHeader-class.html)등이 목록 에 포함하는 위젯의 예입니다 slivers. 이러한 위젯의 대부분은 스크롤이 발생하는 방식을 처리하는 대리자를 사용합니다 .

사용하기 좋은 예로 는 AppBar를 기본적으로 확장하고 스크롤하면 축소하려는 경우 CustomScrollView입니다 .[SliverAppBar](https://api.flutter.dev/flutter/material/SliverAppBar-class.html)

영상

[DraggableScrollableSheet](https://api.flutter.dev/flutter/widgets/DraggableScrollableSheet-class.html)또 다른 예로는 하단에 어떤 동작 버튼을 붙여 놓는 경우 가 있습니다 .

영상

CustomPaint 소개

여기가 바로 플러터가 UI 세계에 최고의 유연성을 제공한 곳입니다.

[CustomPaint](https://api.flutter.dev/flutter/widgets/CustomPaint-class.html)플러터에 대한 _ Canvas API _는 HTML에 대한 것이고 SVG는 이미지에 대한 것입니다.

CustomPaint는 제한 없이 디자인하고 그릴 수 있는 기능을 제공하는 Flutter의 위젯입니다. .으로 그릴 수 있는 캔버스를 제공합니다 [painter](https://api.flutter.dev/flutter/widgets/CustomPaint/painter.html).

영상https://blog.codemagic.io/flutter-custom-painter/에서

CustomPaint를 거의 사용하지 않을 것입니다. 하지만 그것이 존재한다는 것을 알아두십시오. 위젯 조합이 그것을 구현하지 못할 수 있는 매우 복잡한 UI가 있을 수 있고, .으로 그리는 것 외에는 선택의 여지가 없을 것입니다 CustomPaint.

그때가 되면 다른 위젯에 이미 익숙해져서 어렵지 않을 겁니다.

요약

주어진 UI 부분에 대해 위젯을 선택하고, 코드를 작성하고, 다른 위젯과 함께 위젯을 빌드한 다음 Flutter로 어떤 멋진 UI를 구현하고 있는지 확인하세요.

UI 구현은 모바일, 웹 및 데스크톱 앱 개발의 주요 부분입니다. Flutter는 이러한 플랫폼을 위한 크로스 플랫폼을 구축하는 UI 툴킷입니다. Flutter의 선언적 특성과 풍부한 위젯은 UI 구현을 간단하게 만듭니다.

Flutter에서 UI를 계속 구현하세요. 그렇게 하면 두 번째 본성이 될 것입니다. 그리고 Flutter에서 모든 UI를 구현할 수 있을 것입니다.

[출처] https://www.freecodecamp.org/news/how-to-implement-any-ui-in-flutter/

 

 

 

 

 

본 웹사이트는 광고를 포함하고 있습니다.
광고 클릭에서 발생하는 수익금은 모두 웹사이트 서버의 유지 및 관리, 그리고 기술 콘텐츠 향상을 위해 쓰여집니다.
번호 제목 글쓴이 날짜 조회 수
45 [게임 일반] 선택 기반 게임의 표준 패턴 : Standard Patterns in Choice-Based Games 졸리운_곰 2025.01.13 236
44 [게임 일반] SharpMoku a Gomoku/Five in a Row Written in C# : SharpMoku a Gomoku/Five in a Row C#로 작성됨 : 오목게임 개발 file 졸리운_곰 2024.10.31 311
43 [게임 마켓플레이스] 스팀에 ‘게임’을 출시하고 싶다면? file 졸리운_곰 2024.09.07 316
42 [게임 일반] 카드 덱 이미지 (트럼프 카드) 졸리운_곰 2024.05.27 224
41 [게임 개발 일반] 콘솔은 어려울수록, 모바일은 쉬울수록 '돈' 쓴다 file 졸리운_곰 2023.10.30 264
40 [게임 개발 일반] 게임 초기 기획서 작성 방법 졸리운_곰 2023.07.16 250
39 [게임 일반] 하이퍼 캐주얼 모바일 게임 퍼블리셔가 말하는 개발자의 필수 역량은? file 졸리운_곰 2023.02.08 245
38 [게임 일반] 외신, 2D 게임 개발에 적합한 엔진 10종 선정 file 졸리운_곰 2023.01.15 206
37 [게임 일반] 성공적인 하이퍼 캐주얼 게임 제작을 위해 알아야 할 모든 것 졸리운_곰 2023.01.11 192
36 [게임 일반] 게임의 정의와 요소 file 졸리운_곰 2023.01.02 185
35 [게임 일반] 게임(Game), 일상에서 만드는 놀이의 즐거움 file 졸리운_곰 2023.01.02 205
34 [게임 일반] 우리는 왜 게임에 빠지는가 - 게임의 요소와 게임 변천의 역사 졸리운_곰 2023.01.02 250
33 [게임 일반] 재미있는 게임이란? 10부. 게임의 6단계 file 졸리운_곰 2023.01.02 194
32 [게임 일반] 재미있는 게임이란? 9부 -스타2의 패턴전략- file 졸리운_곰 2023.01.02 215
31 [게임 일반] 재미있는 게임이란? 8부 -블리자드의 패턴전략- file 졸리운_곰 2023.01.02 265
30 [게임 일반] 재미있는 게임이란? 7부 -Wow의 패턴전략- file 졸리운_곰 2023.01.02 162
29 [게임 일반] 재미있는 게임이란? 6부 -패턴과 리소스- file 졸리운_곰 2023.01.02 228
28 [게임 일반] 재미있는 게임이란? 5부 -카오스 시스템- file 졸리운_곰 2023.01.02 266
27 [게임 일반] 재미있는 게임이란? 4부 -패턴과 상호작용-' file 졸리운_곰 2023.01.02 186
26 [게임 일반] 재미있는 게임이란? 3부 '게임이 나아가야 할 방향' file 졸리운_곰 2023.01.02 162
대표 김성준 주소 : 경기 용인 분당수지 U타워 등록번호 : 142-07-27414
통신판매업 신고 : 제2012-용인수지-0185호 출판업 신고 : 수지구청 제 123호 개인정보보호최고책임자 : 김성준 sjkim70@stechstar.com
대표전화 : 010-4589-2193 [fax] 02-6280-1294 COPYRIGHT(C) stechstar.com ALL RIGHTS RESERVED