Never give up

Flutter - Splash Screen(Loading screen) 본문

Flutter

Flutter - Splash Screen(Loading screen)

대기만성 개발자 2020. 8. 3. 16:07
반응형

필자가 생각하는 Splash Screen(로딩 화면)사용 이유는 오래걸리는 작업을 할 때
ex) 네트워크에서 API를 불러올때, DB에서 많은 값을 가져올때

첫 화면에서 처리를 해주면 UI rendering중 처리해야될 작업이 줄어들어

앱을 쾌적하게 만들 수 있습니다

 

flutter.dev/docs/development/ui/advanced/splash-screen


위 공식문서에 따르면 Android, IOS 각각 따로 화면을 만들어주는데

비동기처리의 장점을 이용하여 동시에 관리할 수 있습니다

 

비동기 처리의 대한 이해가 필요하다면 링크를 참고해주세요

(링크 : devmemory.tistory.com/50)

import 'package:ex1/main_screen.dart';
import 'package:flutter/material.dart';

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

class _SplashScreenState extends State<SplashScreen> {
  @override
  void initState() {
    super.initState();
    _init();
  }

  void _init() async {
    //오래걸리는 작업 수행

    Navigator.push(
        context, MaterialPageRoute(builder: (context) => MainScreen()));
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.blue,
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            CircularProgressIndicator(
                backgroundColor: Colors.white, strokeWidth: 6),
            SizedBox(height: 20),
            Text('Now loading...',
                style: TextStyle(
                    fontSize: 40,
                    fontWeight: FontWeight.w700,
                    color: Colors.white,
                    shadows: <Shadow>[
                      Shadow(offset: Offset(4, 4), color: Colors.white10)
                    ],
                    decorationStyle: TextDecorationStyle.solid))
          ],
        ),
      ),
    );
  }
}


화면 구성은 build 부분에서 원하는대로 커스텀 하면 되고 

init부분에서 비동기 처리를 이용하면

작업이 끝날때까지 Splash screen이 출력되고 작업이 끝난 후

Navigator를 통해 메인 화면으로 넘어가기 때문에 delay는 사용할 필요가 없습니다

 

가장 주의할점은 build가 끝나기전에 해당 작업이 끝나고

 

Navigator.push 동작이 발생하면 state관련 오류가 발생할 수 있습니다

 

해결 방법은 addPostFrameCallback을 사용하면 조금 더 확실하게 수행할 수 있습니다

(관련 예제 : devmemory.tistory.com/9)

 

그리고 MainScreen에서 onBackPressed를 따로 설정해놓지 않거나 stack에 route가 아직 남아있다면

 

back key를 눌렀을 때 Splash Screen만 계속보이는 상황이 발생하기 때문에 꼭 설정을 해주셔야 됩니다

(참고 : https://devmemory.tistory.com/2)

 

다음 방법은 push와 동시에 해당 route를 remove해주는 방법인데

//splash route name : '/', main route name : '/main'
Navigator.pushNamedAndRemoveUntil(
        context, '/main', ModalRoute.withName('/main'));

//혹은 해당방법을 사용하는데 값이 false이면 하위 루트는 전부 삭제
Navigator.pushNamedAndRemoveUntil(context, '/main', (route) => false);

//MaterialPageRoute를 사용할 경우
Navigator.pushAndRemoveUntil(
    context,
    MaterialPageRoute(builder: (BuildContext context) => MainPage()),
    (route) => false,
  );

onBackPressed를 사용할때도 해당 작업을 해주는게 더 좋을거 같습니다

반응형
Comments