Dev study and notes

플러터 Flutter로 웹툰 앱 만들기 #3 UI CHALLENGE 플러터개발자도구 요소 스크롤 박스 본문

Building & Learning/Flutter로 웹툰앱 만들기(2023)

플러터 Flutter로 웹툰 앱 만들기 #3 UI CHALLENGE 플러터개발자도구 요소 스크롤 박스

devlunch4 2025. 1. 28. 04:00
반응형

안녕하세요 데브런치입니다.

노마드코더의 Flutter로 웹툰 앱 만들기 3번째 챕터 부분 정리, 기록해 보았습니다.

#3 UI CHALLENGE

#3.0 Header (16:47)

어떻게 동작하는지 이해 중점으로 학습합니다.

화면의 각 부분들이 어떻게 구성이 되어 있는지 확인합니다.

천천히 익히면서 합니다.

상단 바 관련 코드 삭제합니다.(appbar 삭제 확인, 아래 스크린샷)

3.0 강좌 최종 소스 -> class app 부분만

 
class App extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        backgroundColor: Color(0xFf181818),
        body: Padding(
          padding: EdgeInsets.symmetric(
            horizontal: 40,
          ),
          child: Column(
            children: [
              SizedBox(
                height: 80,
              ),
              Row(
                mainAxisAlignment: MainAxisAlignment.end,
                children: [
                  Column(
                    crossAxisAlignment: CrossAxisAlignment.end,
                    children: [
                      Text(
                        'Hey, Selena',
                        style: TextStyle(
                          color: Colors.white,
                          fontSize: 28,
                          fontWeight: FontWeight.w800,
                        ),
                      ),
                      Text(
                        "Welcome back",
                        style: TextStyle(
                          color: Colors.white.withOpacity(0.8),
                          fontSize: 18,
                        ),
                      ),
                    ],
                  )
                ],
              )
            ],
          ),
        ),
      ),
    );
  }
}

#3.1 Developer Tools (08:06)

디버그 모드 실행에서 개발자 도구 확인 방법은 아래 디버그 제어창에서 맨 오른쪽 플러터 돋보기를 클릭합니다.

디버그 제어창

클릭을 하게 되면 개발자 도구 창 생성이 됩니다.

개발자 도구창 확인 (widget inspector

생성된 개발자 도구 창을 확인할 수 있습니다.

구성된 구조를 트리구조로 볼수 있습니다.

제어 윈도우 창에서도 수정이 가능합니다(아래 스크린샷)

개발자도구 위젯 제어창에서 수정 가능

vsCode에서 'Toggle select widget mode' 아이콘을 눌러보았습니다.

아이폰 에뮬레이터에서 항목을 클릭시 해당 항목을 vsCode에서 확인 및 보여줍니다.

Toggle select widget mode 사용 예시

개발자 도구에서guidelines 버튼을 누르게 되면 애뮬레이터의 가이드라인을 볼수 있습니다.

guidelines 활성 및 애뮬레이터 가이드라인 확인

이런 개발자 도구 활용을 통해 코딩 또는 화면 작업시 빠르게 확인할 수 있습니다.

#3.2 Buttons Section (10:42)

코드를 넣어 버튼 구현합니다. 소스는 사진 아래 있습니다.

import 'package:flutter/material.dart';

class Player {
  String? name;
  Player();
}

void main() {
  var lunch = Player();
  runApp(App());
}

class App extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        backgroundColor: Color(0xFf181818),
        body: Padding(
          padding: EdgeInsets.symmetric(
            horizontal: 40,
          ),
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              SizedBox(
                height: 80,
              ),
              Row(
                mainAxisAlignment: MainAxisAlignment.end,
                children: [
                  Column(
                    crossAxisAlignment: CrossAxisAlignment.end,
                    children: [
                      Text(
                        "Hey, Selena",
                        style: TextStyle(
                          color: Colors.white,
                          fontSize: 28,
                          fontWeight: FontWeight.w800,
                        ),
                      ),
                      Text(
                        "Welcome back",
                        style: TextStyle(
                          color: Color.fromRGBO(255, 255, 255, 0.8),
                          fontSize: 18,
                        ),
                      ),
                    ],
                  )
                ],
              ),
              SizedBox(
                height: 120,
              ),
              Text(
                "Total Balance",
                style: TextStyle(
                  fontSize: 22,
                  color: Colors.white.withOpacity(0.8),
                ),
              ),
              SizedBox(
                height: 10,
              ),
              Text(
                "\$5 194 482",
                style: TextStyle(
                  fontSize: 48,
                  fontWeight: FontWeight.w600,
                  color: Colors.white,
                ),
              ),
              SizedBox(
                height: 30,
              ),
              Row(
                children: [
                  Container(
                    decoration: BoxDecoration(
                      color: Colors.amber,
                      borderRadius: BorderRadius.circular(45),
                    ),
                    child: Padding(
                      padding: EdgeInsets.symmetric(
                        vertical: 20,
                        horizontal: 50,
                      ),
                      child: Text(
                        "Transfer",
                        style: TextStyle(
                          fontSize: 20,
                        ),
                      ),
                    ),
                  ),
                ],
              ),
            ],
          ),
        ),
      ),
    );
  }
}

#3.3 VSCode Settings (06:18)

코드 작성시 편리하고 유용하도록 vscode 설정하는 방법입니다.

왼쪽 하단의 톱니바퀴(옵션)아이콘을 선택합니다.

이어서 'Command Plette'를 선택합니다.

이어서 검색창에 'Open user Setting'을 타이핑 합니다.

이어서 json 을 선택합니다.

setting.json 파일이 열리게 되며

아래 사진의 드래그한 부분을 타이핑합니다.(시작줄 위의 기존문장 뒤 콤마(,) 입력 확인)

json 파일 저장후 기존 작성하던 main 파일로 이동후

다시 저장(command + s) 하면 자동으로 코드 수정되며 물결줄 문구가 사라집니다.

 

다른 추가 설정으로 아래 스크린샷 내 드래그 부분을 입력 후 저장, vscode를 재시작합니다.

재시작후 main 파일을 확인하면 트리구조로 된 화면으로 보기 편하게 됩니다.

#3.4 Code Actions (04:27)

소스 코드 내에서 해당 소스줄에 마우스를 올리는 경우 전구 아이콘이 생기는데 이것을 선택해봅니다.

여기서 Wrap with Container 를 선택하면 선택했던 소스가 Container 내로 들어오게 됩니다.

 

단축키는 맥기준 command + .(닷) 입니다

#3.5 Reusable Widgets (14:07)

setting.json 설정 및 extension 'Error Lens' 설치를 합니다.(미진행)

기존의 하드코딩을 메소드화 하여 코드길이를 줄이고 활용성 높게 하는 방법 안내입니다.

#3.6 Cards (13:34)

예시 UI 디자인대로 코드를 작성 합니다.

main.dart(아래 소스 코드)

import 'package:flutter/material.dart';
import 'package:toonflix/widgets/Button.dart';

void main() {
  runApp(const App());
}

class App extends StatelessWidget {
  const App({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        backgroundColor: const Color(0xFf181818),
        body: Padding(
          padding: const EdgeInsets.symmetric(
            horizontal: 20,
          ),
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              const SizedBox(
                height: 80,
              ),
              const Row(
                mainAxisAlignment: MainAxisAlignment.end,
                children: [
                  Column(
                    crossAxisAlignment: CrossAxisAlignment.end,
                    children: [
                      Text(
                        "Hey, Selena",
                        style: TextStyle(
                          color: Colors.white,
                          fontSize: 28,
                          fontWeight: FontWeight.w800,
                        ),
                      ),
                      Text(
                        "Welcome back",
                        style: TextStyle(
                          color: Color.fromRGBO(255, 255, 255, 0.8),
                          fontSize: 18,
                        ),
                      ),
                    ],
                  )
                ],
              ),
              const SizedBox(
                height: 120,
              ),
              Text(
                "Total Balance",
                style: TextStyle(
                  fontSize: 22,
                  color: Colors.white.withOpacity(0.8),
                ),
              ),
              const SizedBox(
                height: 10,
              ),
              const Text(
                "\$5 194 482",
                style: TextStyle(
                  fontSize: 48,
                  fontWeight: FontWeight.w600,
                  color: Colors.white,
                ),
              ),
              const SizedBox(
                height: 30,
              ),
              const Row(
                mainAxisAlignment: MainAxisAlignment.spaceBetween,
                children: [
                  Button(
                    text: "Transfer",
                    bgColor: Color(0xFFF1B33B),
                    textColor: Colors.black,
                  ),
                  Button(
                    text: "Request",
                    bgColor: Color(0xFF1F2123),
                    textColor: Colors.white,
                  ),
                ],
              ),
              const SizedBox(
                height: 20,
              ),
              Row(
                crossAxisAlignment: CrossAxisAlignment.end,
                mainAxisAlignment: MainAxisAlignment.spaceBetween,
                children: [
                  const Text(
                    "Wallets",
                    style: TextStyle(
                      color: Colors.white,
                      fontSize: 36,
                      fontWeight: FontWeight.w600,
                    ),
                  ),
                  Text(
                    "View All",
                    style: TextStyle(
                      color: Colors.white.withOpacity(0.8),
                      fontSize: 18,
                    ),
                  ),
                ],
              ),
              const SizedBox(
                height: 20,
              ),
              Container(
                decoration: BoxDecoration(
                  color: const Color(0xFF1F2123),
                  borderRadius: BorderRadius.circular(25),
                ),
                child: Padding(
                  padding: const EdgeInsets.all(30),
                  child: Row(
                    children: [
                      Column(
                        crossAxisAlignment: CrossAxisAlignment.start,
                        children: [
                          const Text(
                            "Euro",
                            style: TextStyle(
                              color: Colors.white,
                              fontSize: 32,
                              fontWeight: FontWeight.w600,
                            ),
                          ),
                          const SizedBox(
                            height: 10,
                          ),
                          Row(
                            children: [
                              const Text(
                                "6 428",
                                style: TextStyle(
                                  color: Colors.white,
                                  fontSize: 20,
                                ),
                              ),
                              const SizedBox(
                                width: 5,
                              ),

#3.7 Icons and Transforms (10:01)

Transform.scale 사용 방법입니다.

  • 박스내의 요소의 크기를 조절하거나 내부 요소의 여러 요소들을 수정할수 있습니다
  • 유로 달러 기호 변경

clipBehavior 사용 방법입니다.

  • 박스내의 요소가 크기에 의해 벗어날때 내부안에서만 보이게 자르는 식으로 보여줍니다.
  • clip.hardEdge 값 설정시 박스내 벗어난 기호부분을 잘라 삭제하여 보여줍니다.

#3.8 Reusable Cards (14:44)

currency_card.dart 를 생성하여 UI의 카드 부분을 재사용/생성 합니다.

화면 전체 보기위해 스크롤을 생성합니다.

카드 부분을 겹치게 합니다.

main.dart(소스코드)

import 'package:flutter/material.dart';
import 'package:toonflix/widgets/Button.dart';
import 'package:toonflix/widgets/currency_card.dart';

void main() {
  runApp(const App());
}

class App extends StatelessWidget {
  const App({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        backgroundColor: const Color(0xFf181818),
        body: SingleChildScrollView(
          child: Padding(
            padding: const EdgeInsets.symmetric(
              horizontal: 20,
            ),
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                const SizedBox(
                  height: 80,
                ),
                const Row(
                  mainAxisAlignment: MainAxisAlignment.end,
                  children: [
                    Column(
                      crossAxisAlignment: CrossAxisAlignment.end,
                      children: [
                        Text(
                          "Hey, Selena",
                          style: TextStyle(
                            color: Colors.white,
                            fontSize: 28,
                            fontWeight: FontWeight.w800,
                          ),
                        ),
                        Text(
                          "Welcome back",
                          style: TextStyle(
                            color: Color.fromRGBO(255, 255, 255, 0.8),
                            fontSize: 18,
                          ),
                        ),
                      ],
                    )
                  ],
                ),
                const SizedBox(
                  height: 70,
                ),
                Text(
                  "Total Balance",
                  style: TextStyle(
                    fontSize: 22,
                    color: Colors.white.withOpacity(0.8),
                  ),
                ),
                const SizedBox(
                  height: 10,
                ),
                const Text(
                  "\$5 194 482",
                  style: TextStyle(
                    fontSize: 48,
                    fontWeight: FontWeight.w600,
                    color: Colors.white,
                  ),
                ),
                const SizedBox(
                  height: 30,
                ),
                const Row(
                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
                  children: [
                    Button(
                      text: "Transfer",
                      bgColor: Color(0xFFF1B33B),
                      textColor: Colors.black,
                    ),
                    Button(
                      text: "Request",
                      bgColor: Color(0xFF1F2123),
                      textColor: Colors.white,
                    ),
                  ],
                ),
                const SizedBox(
                  height: 50,
                ),
                Row(
                  crossAxisAlignment: CrossAxisAlignment.end,
                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
                  children: [
                    const Text(
                      "Wallets",
                      style: TextStyle(
                        color: Colors.white,
                        fontSize: 36,
                        fontWeight: FontWeight.w600,
                      ),
                    ),
                    Text(
                      "View All",
                      style: TextStyle(
                        color: Colors.white.withOpacity(0.8),
                        fontSize: 18,
                      ),
                    ),
                  ],
                ),
                const SizedBox(
                  height: 20,
                ),
                /////
                const CurrencyCard(
                  name: "Euro",
                  code: "EUR",
                  amount: "6 428",
                  icon: Icons.euro_rounded,
                  isInverted: false,
                ),
                Transform.translate(
                  offset: const Offset(0, -20),
                  child: const CurrencyCard(
                    name: "Bitcoin",
                    code: "BTC",
                    amount: "9 990",
                    icon: Icons.currency_bitcoin,
                    isInverted: true,
                  ),
                ),
                Transform.translate(
                  offset: const Offset(0, -40),
                  child: const CurrencyCard(
                    name: "Dollar",
                    code: "USD",
                    amount: "6 425",
                    icon: Icons.attach_money,
                    isInverted: false,
                  ),
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }
}

#3.9 Code Challenge (04:05)

지금까지 작성한 코드에서 박스카드 부분의 transform 부분을 currency_card.dart 부분에 넣고

offset 요소도 넣어 메소드화 합니다.

끝!

반응형
Comments