본문 바로가기
관리자

Programming-[CrossPlatform]/Flutter

Flutter 기본-15. 채팅앱 - 로그인 기본 구조: Positioned, MediaQuery.of

728x90
반응형

Youtube 코딩셰프님의 강의를 요약 정리한 글이다. dart 언어나 이론 부분은 자바와 유사하여 대부분 제외하였고, flutter 기초 위주로 정리한다.

https://www.youtube.com/@codingchef

 

코딩셰프

향후 대세가 될 플러터를 단계별로 맛있게 학습하실 수 있습니다!

www.youtube.com

 

 

 

in-app background image reference : https://wallpapercave.com/cartoon-chickens-wallpapers


이제 로그인 및 채팅이 가능한 채팅앱을 만든다. 이번 글에서는 UI 만들기에 집중한다. 강의에서 설명하는 것처럼 UI 작성에 익숙해지기 위한 과정으로 최대한 리팩토링을 자제하고 하나의 파일에 쭉 이어서 만든다. 앞서 배웠던 부분들도 활용하겠지만, 주로 새로 나온 부분들을 위주로 정리해놓는다.

 

1. 전체 구조

 

디렉토리 구조

아래사진 처럼 구성한다.

 

 

palette, painting.dart

여러 색깔 값들을 참고하기 위해서 lib/config/palette.dart 파일을 만들고 아래 코드들을 추가한다.  여기서 import 하는 painting.dart는 나중에 login_screen 에서도 추가해서 BorderRadius, BoxDecoration 등 다양한 UI관련 위젯들을 활용하게 된다. 자세한 내용은 아래 링크에서 볼 수 있다.

https://api.flutter.dev/flutter/painting/painting-library.html

import 'package:flutter/painting.dart';

class Palette{
  static const Color iconColor = Color(0xFFB6C7D1);
  static const Color activeColor = Color(0xFF09126C);
  static const Color textColor1 = Color(0XFFA7BCC7);
  static const Color textColor2 = Color(0XFF9BB3C0);
  static const Color facebookColor = Color(0xFF3B5999);
  static const Color googleColor = Color(0xFFDE4B39);
  static const Color backgroundColor = Color(0xFFECF3F9);
}

 

 

main_screen 기본 구조

아래 코드 구조로 쌓아나간다. LoginSignupScreen을 main.dart에서 MaterialApp의 home:에 등록한다. 그리고 Scaffold의 body에는 Stack을 만들어서 여러 위젯들을 쌓아나가는 형태로 만들 것이다.

 

그리고 사용자가 화면상의 요소들을 탭 했을 때 어떤 동작의 기준이 될 수 있도록 isSignupScreen 변수값도 초기화해주었다.

import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';

import '../config/palette.dart';

class LoginSignupScreen extends StatefulWidget {
  const LoginSignupScreen({Key? key}) : super(key: key);

  @override
  State<LoginSignupScreen> createState() => _LoginSignupScreenState();
}

class _LoginSignupScreenState extends State<LoginSignupScreen> {
  bool isSignupScreen = true;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Palette.backgroundColor,
      body: Stack(
        children: [
          
        ],
      )
    );
  }
}

 

 

 

2. Background: Image, Text

 

Positioned

Stack 위에 위치를 조정할 수 있고, 나중에는 애니메이션 기능을 가진 위젯으로 전환할 수 있는 Positioned 위젯으로 위젯들을 쌓아나간다.

 

신규 인자값 및 위젯들

  • decoration: BoxDecoration
  • DecorationImage
  • BoxFit.cover

@override
Widget build(BuildContext context) {
  return Scaffold(
      backgroundColor: Palette.backgroundColor,
      body: Stack(
        children: [
          Positioned(
              top: 0,
              right: 0,
              left: 0,
              child: Container(
                height: 300,
                decoration: BoxDecoration(
                    image: DecorationImage(
                  image: AssetImage('image/background_image.jpeg'),
                  fit: BoxFit.cover,
                      opacity: 0.7
                )
                ),
              )
          )
        ],
      )
  );

 

 

텍스트 표현: RichText, TextSpan

child: Container(
  padding: EdgeInsets.only(top: 90, left: 20),
  child: Column(
    crossAxisAlignment: CrossAxisAlignment.start,
    children: [
      RichText(
        text: TextSpan(
          text: 'Welcome',
          style: TextStyle(
            letterSpacing: 1.0,
            fontSize: 25,
            color: Colors.black
          ),
          children: [
            TextSpan(
              text: ' to Chicken Chat',
              style: TextStyle(
                  letterSpacing: 1.0,
                  fontSize: 25,
                  color: Colors.black,
                fontWeight: FontWeight.bold
              ),
            )
          ]
        ),
      )
    ],
  ),
),

 

Container의 child로 또 다른 Container를 삽입 후, padding 및 Text들을 추가했다. 

  • RichText: 폰트, 크기와 특징이 다른 텍스트들을 한 번에 표현하고 싶을 때 사용. children 인자를 받아와서 또 다른 TextSpan을 추가하는 방식으로 사용한다.
  • TextSpan: 텍스트나 문단을 모아서 구성할 수 있다.

 

아래 그림을 보면 RichText 바깥쪽에(Column의 children 부분) SizedBox와 Text를 추가하여 signup to continue 라는 문구를 다른 줄에 표기해주었다.

 

 

 

위젯 정리

다른 위젯 작업을 위해 Positioned 위젯을 cmd + . 키를 누르거나 왼쪽 bar의 -버튼을 눌러 축소해놓는다. 그리고 구분을 위해 주석을 달아놓는다.

 

 

 

3. Login, Signup 골격 만들기

 

BoxDecoration, MediaQuery

Positioned 위젯을 추가하고 BoxDecoration으로 Box형태를 만든다.

 

body: Stack(
  children: [
    Positioned(...),//background,
    Positioned(
      top: 180,
        child: Container(
      height: 280.0,
      width: MediaQuery.of(context).size.width-40,
      margin: EdgeInsets.symmetric(horizontal: 20.0),
      decoration: BoxDecoration(
        color: Colors.white,
        borderRadius: BorderRadius.circular(15.0),
        boxShadow: [
          BoxShadow(
            color: Colors.black.withOpacity(0.3),
            blurRadius: 15,
            spreadRadius: 5
          )
        ]
      ),
    )
    )
  ],
)

 

MediaQuery.of(context).size.width 로 기기나 View 환경에 상관없이 사용자가 보는 화면의 가로 너비값을 구해올 수 있다.

BoxDecoration으로 Box 형태를 만들고, BorderRadius, BoxShadow 값을 줄 수 있다.

 

 

LOGIN, SIGNUP 버튼 만들기 : GetstureDetector, setState

child: Column(
  children: [
    Row(
      mainAxisAlignment: MainAxisAlignment.spaceAround,
      children: [
        GestureDetector(
          onTap: () {
            setState(() {
              isSignupScreen = false;
            });
          },
          child: Column(
            children: [
              Text('LOGIN',
              style: TextStyle(
                color: !isSignupScreen? Palette.activeColor : Palette.textColor1,
                fontSize: 20.0,
                fontWeight: FontWeight.bold,
              ),
              ),
              SizedBox(
                height: 5.0,
              ),
              Container(
                height: 2.0,
                width: 50.0,
                color: Colors.brown,
              )
            ],
          ),

 

Row와 Column을 반복되는 트리구조로 만들어서 LOGIN, SIGNUP 버튼을 만든다. 새로 배운 사항들은 다음과 같다.

  • Container 자체로 밑줄 효과를 만들 수 있다.
  • 텍스트 디자인을 다 해놓고, Column 위젯을 GestureDector로 감싸서 setState 처리한다.

 

*spaceBetween, spaceAround, spaceEvenly 차이

https://kotlinworld.com/195

모두 다 각 요소간 간격을 동일하게 맞추지만, between은 양 끝 요소의 바깥쪽 여백이 남지 않게, around는 양 끝 요소의 바깥쪽 여백이 간격의 절반만큼만 되도록, evenly는 양 끝 요소의 바깥쪽 여백이 간격과 같게 맞춘다.

 

 

 

삼항연산자 적용

마지막으로 삼항연산자를 적용하여 각 위젯의 color를 바꿀 수 있다. LOGIN 위젯 부분을 클릭했을 때는 isSignupScreen 변수 앞에 !를 붙여서 부정을 해줬다. SIGNUP 위젯에는 반대로 적용해주면 된다!

 

 

 

728x90
반응형