๊ด€๋ฆฌ ๋ฉ”๋‰ด

Whaeun Story

[Flutter] ํŽ˜์ด์ง€ ์ด๋™ ๋ณธ๋ฌธ

๊ณต๋ถ€/flutter

[Flutter] ํŽ˜์ด์ง€ ์ด๋™

whaeun 2022. 2. 11. 09:35

๐Ÿ“Œ ํ•™์Šต ๋ชฉ๋ก ๐Ÿ“Œ

  1. ํŽ˜์ด์ง€ ์ด๋™
  2. Splash ํ™”๋ฉด ๊ตฌํ˜„

๐Ÿ‘ฉ๐Ÿฝ‍๐Ÿ’ป ํ•™์Šต ๋‚ด์šฉ

  1. ํŽ˜์ด์ง€ ์ด๋™
  • Navigator
    : Stack์„ ์ด์šฉํ•˜์—ฌ ํ•˜์œ„ ์œ„์ ฏ(ํ™”๋ฉด) ์ง‘ํ•ฉ์„ ๊ด€๋ฆฌํ•˜๋Š” ์œ„์ ฏ์ด๋‹ค. ๊ฐ€์žฅ ์ตœ๊ทผ์— ๋ฐฉ๋ฌธํ•œ ํŽ˜์ด์ง€๊ฐ€ ์ด์ „ ํŽ˜์ด์ง€ ์œ„์— ์‹œ๊ฐ์ ์œผ๋กœ ์ค‘์ฒฉ๋˜์–ด ๋…ผ๋ฆฌ ๊ธฐ๋ก์„ ํ‘œ์‹œํ•˜๊ธฐ ์œ„ํ•ด ์œ„์ ฏ ๊ณ„์ธต ๋งจ ์œ„์— navigator๊ฐ€ ์žˆ์–ด ์ด์ „ ํŽ˜์ด์ง€๋กœ์˜ ์ด๋™์„ ์‹œ๊ฐ์ ์œผ๋กœ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.
  • Navigator.push()
    : push() ๋ฉ”์„œ๋“œ๋Š” Route๋ฅผ Navigator์— ์˜ํ•ด ๊ด€๋ฆฌ๋˜๋Š” route ์Šคํƒ์— ์ถ”๊ฐ€ํ•œ๋‹ค.
  • Navigator.pop()
    : pop() ๋ฉ”์„œ๋“œ๋Š” Navigator์— ์˜ํ•ด ๊ด€๋ฆฌ๋˜๋Š” route ์Šคํƒ์—์„œ ํ˜„์žฌ Route๋ฅผ ์ œ๊ฑฐํ•œ๋‹ค.
    *์ฒซ ํŽ˜์ด์ง€๋ฅผ ์ œ์™ธํ•˜๊ณ ๋Š” appBar์˜ ๋’ค๋กœ๊ฐ€๊ธฐ ๋ฒ„ํŠผ์ด ์ž๋™์ ์œผ๋กœ ์ƒ์„ฑ๋˜๊ณ  pop์ด ๋“ค์–ด๊ฐ€๊ฑฐ๋‚˜ appBar๋ฅผ ๋งŒ๋“ค์ง€ ์•Š๊ฒŒ ๋˜๋ฉด ๋’ค๋กœ๊ฐ€๊ธฐ ๋ฒ„ํŠผ์ด ์ƒ์„ฑ๋˜์ง€ ์•Š๋Š”๋‹ค.
  • Navigator.pushNamedAndRemoveUntil(context, '/', (_) => false);
    ์ง€๊ธˆ๊นŒ์ง€์˜ route์— ์Œ“์ธ ๋ชจ๋“  ํŽ˜์ด์ง€๋ฅผ ์‚ญ์ œํ•˜๊ณ  ์‹ถ์„ ๊ฒฝ์šฐ ์‚ฌ์šฉํ•œ๋‹ค.
  • ์‚ฌ์šฉ ์˜ˆ์‹œ

login.dart ์ผ๋ถ€

//ํ•ด๋‹น ๋ถ€๋ถ„์€ ๋กœ๊ทธ์ธ ๋ฒ„ํŠผ์„ ๋ˆŒ๋ €์„ ๋•Œ ๋™์ž‘ํ•˜๋Š” ํ•จ์ˆ˜๋กœ ํ•ด๋‹น ์ž…๋ ฅ ์–‘์‹์ด ์˜ฌ๋ฐ”๋ฅธ์ง€ ํ™•์ธํ•˜๊ณ  ์ž…๋ ฅ ์–‘์‹์ด ์˜ฌ๋ฐ”๋ฅผ ๊ฒฝ์šฐ, ๋ชจ๋“œ๋ฅผ ์„ ํƒํ•  ์ˆ˜ ์žˆ๋Š” ํ™”๋ฉด์œผ๋กœ ์ „ํ™˜ํ•ด ์ฃผ๋Š” ์—ญํ• ์„ ํ•œ๋‹ค.

 void validateAndSave() {
    final form = formKey.currentState;
    if (form!.validate()) {
      form.save();
      print('Form is valid Email: $_email, password: $_password');
      
      // ํ˜„์žฌ ํ™”๋ฉด์„ route ์Šคํƒ์—์„œ popํ•˜์—ฌ ์ œ๊ฑฐํ•œ๋‹ค.
      Navigator.pop(context);
      // ๋ถˆ๋Ÿฌ์˜ค๊ณ  ์‹ถ์€ ํ™”๋ฉด์„ route ์Šคํƒ์—์„œ pushํ•˜์—ฌ ์ถ”๊ฐ€ํ•œ๋‹ค. ์—ฌ๊ธฐ์—์„œ๋Š” selectModeMainPage๋ฅผ ์Šคํƒ์— ์ถ”๊ฐ€ํ•œ๋‹ค.
      Navigator.push(context, MaterialPageRoute(builder: (context) => selectModeMainPage()),);
      //์—ฌ๊ธฐ์„œ๋Š” ๋กœ๊ทธ์ธ์ด ์™„๋ฃŒ๋œ ํ›„์—๋Š” ๋กœ๊ทธ์•„์›ƒ์„ ํ•˜์ง€ ์•Š๋Š” ์ด์ƒ ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€๋กœ ๋Œ์•„์˜ค์ง€ ์•Š๋„๋ก ์„ค์ •ํ•ด์•ผ ํ•˜๋ฏ€๋กœ ํ˜„์žฌ ํŽ˜์ด์ง€๋ฅผ popํ•ด์ค€๋‹ค.

    } else {
      print('Form is invalid Email: $_email, password: $_password');
    }
  }
  1. Splash ํ™”๋ฉด ๊ตฌํ˜„
  • Splash Screen(Launch Screen): ์•ฑ์„ ๊ตฌ๋™ํ•  ๋•Œ ๋ณด์—ฌ์ฃผ๋Š” ์‹œ์ž‘ํ™”๋ฉด์„ ์ด์•ผ๊ธฐํ•œ๋‹ค.
  • ๊ตฌํ˜„ ๋ฐฉ๋ฒ•
1) pubspec.yaml์— ์ด๋ฏธ์ง€๋ฅผ ์„ ์–ธํ•œ๋‹ค.
  - ํ”„๋กœ์ ํŠธ์— ์ด๋ฏธ์ง€๋ฅผ ๋„ฃ์„ ํด๋”๋ฅผ ๋งŒ๋“ค์–ด ๋†“๊ณ  splash ํ™”๋ฉด์— ์‚ฌ์šฉํ•  ์ด๋ฏธ์ง€๋ฅผ ์ด๋ฏธ์ง€ ํด๋” ์•ˆ์— ๋„ฃ์–ด ๋†“๋Š”๋‹ค.
  - ์ด๋ฏธ์ง€๋ฅผ ์„ ์–ธํ•  ๋•Œ, ํด๋” ์ „์ฒด๋ฅผ ์„ ์–ธํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ ๊ทธ๋Ÿด ๊ฒฝ์šฐ ํ•ด๋‹น ํด๋” ์•ˆ์— ์†ํ•ด ์žˆ๋Š” ์ด๋ฏธ์ง€๋“ค์„ ์ „๋ถ€ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋œ๋‹ค.
  - ์„ ์–ธ์„ ์™„๋ฃŒํ•œ ํ›„์—๋Š” "Pub get"์„ ํ•ด์ฃผ๊ณ  ์ด์–ด์„œ "Pub Upgrade"๋ฅผ ํ•œ๋‹ค.
  
2) main.dart ์„ค์ •
  - ์Šคํ”Œ๋ž˜์‹œ ํ™”๋ฉด ์ดํ›„์— ๋‚˜์˜ค๊ฒŒ ํ•  ํ™”๋ฉด์˜ ๊ฒฝ๋กœ๋ฅผ importํ•œ๋‹ค.
  - _SplashScreenState์—์„œ timer๋ฅผ ์„ค์ •ํ•œ๋‹ค. Duration()์œผ๋กœ ์‹œ๊ฐ„ ์„ค์ •์ด ๊ฐ€๋Šฅํ•˜๋‹ค.
  - initState์™€ build๋ฅผ ํ†ตํ•ด ํƒ€์ด๋จธ ์‹œ์ž‘์„ ์„ค์ •ํ•œ๋‹ค.
  - Widget build๋กœ pubspec.yaml์—์„œ ์„ ์–ธํ•ด ๋‘์—ˆ๋˜ ์ด๋ฏธ์ง€ ๊ฒฝ๋กœ๋ฅผ ๊ฐ€์ ธ์˜จ๋‹ค.
  • ์‚ฌ์šฉ ์˜ˆ์‹œ

pubspec.yaml ์ผ๋ถ€

flutter:
  uses-material-design: true
  assets:
    - images/

main.dart

import 'dart:async';

import 'package:flutter/material.dart';
import 'Login/login.dart';

void main() {
  runApp(new MaterialApp(
    home: new SplashScreen(),
    routes: <String, WidgetBuilder>{
      // '/login'์˜ ๊ฒฝ์šฐ LoginPage์™€ ์—ฐ๊ฒฐ๋˜๋„๋ก ์„ค์ •
      '/login': (BuildContext context) => new LoginPage()
    },
  ));
}

class SplashScreen extends StatefulWidget {
  @override
  _SplashScreenState createState() => new _SplashScreenState();
}

class _SplashScreenState extends State<SplashScreen> {

  startTime() async {
    // 2์ดˆ๊ฐ€ ์ง€๋‚˜๋ฉด navigationPageํ•จ์ˆ˜๊ฐ€ ์ž‘๋™๋œ๋‹ค.
    var _duration = new Duration(seconds: 2);
    return new Timer(_duration, navigationPage);
  }

  void navigationPage() {
    // ์œ„์— ์„ค์ •ํ•ด ์ค€ ๊ฒƒ์„ ๋ฐ”ํƒ•์œผ๋กœ LoginPage๋กœ ์ด๋™ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋จ.
    Navigator.of(context).pushReplacementNamed('/login');
  }

  @override
  void initState() {
    // ์•ฑ์ด ์‹œ์ž‘๋˜๋ฉด ์‹œ๊ฐ„์„ ์žฌ๊ธฐ ์‹œ์ž‘ํ•œ๋‹ค.
    super.initState();
    startTime();
  }

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      body: new Center(
        // ์•ฑ์˜ ๋กœ๊ณ ๊ฐ€ ์Šคํ”Œ๋ž˜์‹œ ํ™”๋ฉด์œผ๋กœ ๋œจ๊ฒŒ ๋œ๋‹ค.
        child: new Image.asset('images/zerozonelogo.png'),
      ),
    );
  }
}

๐Ÿ’ฅ Trouble Shooting ๐Ÿ’ฅ

- "unable to load asset"์—๋Ÿฌ
์‹œ๋ฎฌ๋ ˆ์ดํ„ฐ๋Š” ์ •์ƒ์ ์œผ๋กœ ์‹คํ–‰์ด ๋˜์—ˆ์ง€๋งŒ ์Šคํ”Œ๋ž˜์‹œํ™”๋ฉด์— ๋‚˜ํƒ€๋‚˜๋„๋ก ์„ค์ •ํ–ˆ๋˜ ์ด๋ฏธ์ง€๊ฐ€ ๋‚˜ํƒ€๋‚˜์ง€ ์•Š๊ณ  unable to load asset์ด๋ผ๋Š” ๋ฉ”์‹œ์ง€๊ฐ€ ๋‚˜ํƒ€๋‚ฌ๋‹ค.
=> ํ•ด๊ฒฐ๋ฐฉ๋ฒ•:

1) images ํด๋”์˜ ์œ„์น˜ ์˜ค๋ฅ˜ - lib ํด๋” ๋ฐ–์— ์œ„์น˜ ์‹œํ‚จ๋‹ค.

2) pubspec.yaml ํŒŒ์ผ์—์„œ ๋„์–ด์“ฐ๊ธฐ ๊ตฌ๋ถ„์„ ํ•ด์ฃผ์–ด์•ผ ํ•œ๋‹ค.
assets ์ „์— ๋„์–ด์“ฐ๊ธฐ 2๋ฒˆ ํ˜น์€ ํƒญ 1๋ฒˆ, ์ดํ›„ - ์ด๋ฏธ์ง€ ๊ฒฝ๋กœ ์ „์— ๋„์–ด์“ฐ๊ธฐ 4๋ฒˆ ํ˜น์€ ํƒญ 2๋ฒˆ์„ ํ•ด์•ผ ํ•œ๋‹ค.

๐Ÿ“ ์ฐธ๊ณ  ์ž๋ฃŒ

'๊ณต๋ถ€ > flutter' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

HTTP ํ†ต์‹   (0) 2022.12.18
Advanced UI & Animations  (0) 2022.12.17
dart ์–ธ์–ด ํ•™์Šต [2]  (0) 2022.11.28
dart ์–ธ์–ด ํ•™์Šต [1]  (0) 2022.11.28
[Flutter] Flutter ์‹œ์ž‘  (2) 2022.01.23