본문 바로가기

개발 코딩 정보 공유/플루터 Flutter

flutter (플러터) 배우기 - 개념과 기초구현

 

 

안녕하세요. 김과자입니다.

최근 핫한 개발 프레임워크 이죠. 플러터(플루터) 알아봅시다.

플러터는 구글이 개발 오픈 소스 모바일 애플리케이션 개발 프레임워크 입니다.

안드로이드, iOS 애플리케이션 개발을 위해 세상에 나오게되었습니다.

사실 전에도 크로스플랫폼 개발 위한 프레임워크들이 있었죠.

예를 들어 phonegap, cordova, ionic, react native...등등

이들의 목표 자체는 아마도 이것이겠죠?

 

한가지 방법 한번의 구현으로 여러가지 플랫폼을 일타쌍피!!신공

 

... 생각만해도 너무 좋지만. 그에따른 이슈도 너무 많습니다.

그럼 어찌어찌 개발을 했다고 해서 native 몰라도 되는가? 그것도 아니란 말이죠.

결국엔 네이티브 작업을 해줘야하죠. 정도의 차이일뿐.

 

어찌되었든 플러터 역시 그와같은 크로스플랫폼개발을 위해 등장하였습니다.

구글 플러터 공식문서를 활용해서 간략한 예제를 통해

같이 한번 개념도 살펴보고 간단한 구현도 해보겠습니다.

 

https://flutter-ko.dev/docs/get-started/flutter-for/android-devs

 

문서에 보면 다른 플랫폼을 사용하던 개발자에게

쉽게 접근이 가능하도록 아주 유용한 문서들을 제공하고 있는데요.

우리는 "Android 개발자를 위한 Flutter" 문서를 활용해 보겠습니다.

안드로이드에 있는 개념과 플러터에 있는 개념을 섞어서 비교해 가면서

설명해주고있습니다.

 

필요한 부분에 가장 적합한 질문을 찾아내는 방식으로  문서를 요리책(cookbook)처럼 활용하실 수도 있습니다.

 

안드로이드에서 나타나는 모든 것은 '' 기반이죠.

플러터에서 뷰에 해당하는것은 무엇일까요?

 

"Flutter에서는 위젯이 뷰와 유사합니다위젯이 Android 뷰와 정확하게 일치하는  아니지만
Flutter 익힐  위젯이 “UI 선언하고 구성하는 방식이라고 이해할  있습니다."

 

완벽히 일치하는 개념은 아니지만 뷰와 비슷하게 퉁쳐서 생각하면 된다고 하네요.

그렇지만 flutter 에서의 위젯은 뷰와 조금 다르게 동작합니다.

위젯은 생명주기가 없으며, 불변의 객체입니다. 그렇기때문에 가볍고 빠르게 동작하죠.

 

"위젯 혹은 위젯의 상태가 변경되면. Flutter 위젯 인스턴스의 새로운 트리를 생성합니다반면, Android 뷰는  번만 그려지고, invalidate 호출되기 전까지는 다시 그리지 않습니다."

 

플러터는 선언적 프로그래밍(스타일) 방식을 채택하고있습니다.

기존 대부분의 언어들의 방식인 명령형 어떤게 다른지 한번 참고해보시면 좋겠네요.

 

https://flutter-ko.dev/docs/get-started/flutter-for/declarative

 

위젯이 불변이라면 어떤게 변경할수 있을까?

안드로이드라면 뷰를 직접 수정하여 변경사항을 적용하면되죠.

하지만 Flutter에서 위젯은 불변이기 때문에 직접 변경할 없고,

대신 위젯의 state(상태) 변경할 있습니다

지금쯤이면 이게 대체 무슨말이냐...??? 하실겁니다.

소스를 한번 보겠습니다.

 

Text(
  'I like Flutter!',
  style: TextStyle(fontWeight: FontWeight.bold),
);

 

Text 위젯은 일반적인 StatelessWidget 인데요.

불변위젯이라는 말이죠. 생성자를 통해 전달한 말고

동적으로 어떻게 변경하면 될까요?

아래 소스 보겠습니다. (다소 난해할수도 있으니 일단 훑어봅시다. 처음이니까요.)

 

import 'package:flutter/material.dart';

void main() {
  runApp(SampleApp());
}

class SampleApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Sample App',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: SampleAppPage(),
    );
  }
}

class SampleAppPage extends StatefulWidget {
  SampleAppPage({Key key}) : super(key: key);

  @override
  _SampleAppPageState createState() => _SampleAppPageState();
}

class _SampleAppPageState extends State<SampleAppPage> {
  // Default placeholder text
  String textToShow = "I Like Flutter";

  void _updateText() {
    setState(() {
      // update the text
      textToShow = "Flutter is Awesome!";
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Sample App"),
      ),
      body: Center(child: Text(textToShow)),
      floatingActionButton: FloatingActionButton(
        onPressed: _updateText,
        tooltip: 'Update Text',
        child: Icon(Icons.update),
      ),
    );
  }
}

 

전체적인 흐름을 보면 이렇습니다.

 

main -> SampleApp(StatelessWidget) -> SampleAppPage(StatefulWidget) -> _SampleAppPageState (State)

 

초기값을 할당해줬구요.

 

String textToShow = "I Like Flutter";

 

값으로 빌드쪽을 타겠죠.

 

Widget build(BuildContext context){
  ...
  body: Center(child: Text(textToShow)),
}

이부분 보이시죠?

이부분에서 텍스트위젯에 값을 생성자에 넣어주고있습니다.

그럼 당연히 "I Like Flutter" 라고화면에 찍히겠죠.

 

//이 부분이 중요합니다. 버튼을 하나 띄워줍니다.
floatingActionButton: FloatingActionButton(
  onPressed: _updateText,
  tooltip: 'Update Text',
  child: Icon(Icons.update),
),

 

그리고 이 부분에 보면 "_updateText" 함수를 따라가보죠.

 

onPressed: _updateText,
//여기있죠. 보면 이상한게 하나 있습니다.
void _updateText() {
  setState(() {
    // update the text
    textToShow = "Flutter is Awesome!";
  });
}

 

이놈인데요. 뭘까요?

 

setState(() {

 

어라? 이안에서 값을 변경합니다.

 

textToShow = "Flutter is Awesome!";

 

~ 이제 감이오죠? 맞습니다.

 

setState() 호출되면 그안에 구현한 값이

변경됩니다. 그리고 위젯이 다시 빌드됩니다.

 

그럼 이부분을 다시 타겠죠?

 

Widget build(BuildContext context)

 

이와 같은 흐름이 플루터의 기본적인 동작 방식입니다.

이후에 bloc 패턴 등을 쓴다고 해도 기본적인 개념은 변하지 않죠.

 

안드로이드처럼 따로 xml 구조의 화면 레이아웃이 없으므로

조금. 겁이날수 있지만. 자세히 보면 어렵지 않습니다.

차라리 js 프레임워크들로 프론트엔드 개발을 해보셨던 분들은 보기 수월할것 같네요.

 

자. 헷갈리신다면 이것만 기억하시면 됩니다. 변경되지 않는것은 StatelessWidget 으로 처리하고 UI 동적으로 변경된다면 StatefulWidget 사용하여 구현하자.

 

그럼 다음시간에 또 이야기 해보겠습니다.

 

 

 

끝.