[Flutter] StatefulWidget()

Tyger·2021년 10월 18일
0

StatefulWidget()

Flutter project를 처음 실행하면 기본으로 작성되있는 count up 코드가 있다
이 코드가 StatefulWidget으로 작성된 코드이다

Flutter 개발에 있어서 가장 많이 사용하게 되는 widget이 StatelessWidget, StatefulWidget 이렇게 2종류의 state widget을 가장 자주 사용한다

실제 project에서는 상태관리 때문에(?) StatefulWidget은 사용하지 않는다

StatefulWidget과 StatelessWidget의 차이는 상태가 있고 없고의 차이라 한다
처음에 flutter 개발을 할 때 두 위젯의 차이를 이해하지 못했었다
그냥 StatefulWidget으로 작성하면 편하게 상태관리를 할 수 있는데 StatelessWidget은 왜 있는건지..
하지만 앱의 규모가 점점 커지면서 상태관리가 엉망이 되기 시작했고, 상태관리에 대해 공부하다 보니 이제는 StatefulWidget은 아예 사용을 안하게 되었다.

StatefulWidget은 setState안에 원하는 event를 주면 앱에 바뀌는 상태를 다시 그리게 된다
build 아래에 print를 찍어보면 한 부분의 event를 변경할 때도 rebuild 되는 것을 확인 할 수 있다
이 부분때문에 StatefulWidget을 사용하지 않는다

Bloc, cubit, provider, getX 등 pub.dev를 접속해 보면 유명한 상태관리 기법들이 있다
flutter 개발 초기에는 비교적 사용이 쉬운 provider 위주로 상태관리를 하였지만 현재는 주로 Bloc만 사용한다(getX는 사용해보지 못했다)

그렇다해도 StatefulWidget을 이해하고 개발을 시작하는 것을 추천한다

StatefulWidget과 StatelessWidget의 기본 코드를 살펴보면 createState라는 부분이 있다
setState안에 event를 호출하면 creatState가 앱을 다시 그린다고 알고있다
StatelessWidget에는 이 부분이 없다

자세한 내용은 flutter reference를 보도록 하자

아래 코드는 그대로 실행하면 실행이 될 것이다
설명 없이 코드만 올리겠음

import 'package:flutter/material.dart';

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

  
  _VelogWidgetStatefulState createState() => _VelogWidgetStatefulState();
}

class _VelogWidgetStatefulState extends State<VelogWidgetStateful> {
  int count = 0;
  bool isToggle = false;
  int colorsChanged = 0;
  int animatedCount = 0;
  bool textStyleChanged = false;
  bool containerChanged = false;
  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Colors.white,
        title: const Text('Stateful'),
        actions: [
          InkWell(
            onTap: () {
              setState(() {
                count = 0;
                isToggle = false;
                colorsChanged = 0;
                animatedCount = 0;
                textStyleChanged = false;
                containerChanged = false;
              });
            },
            child: const Padding(
              padding: EdgeInsets.only(right: 20),
              child: Icon(Icons.autorenew_rounded),
            ),
          )
        ],
      ),
      body: Column(
        children: [
          _widgetForm(
              onTap: () {
                setState(() {
                  count++;
                });
              },
              widget: Text(count.toString())),
          _widgetForm(
              onTap: () {
                setState(() {
                  isToggle = !isToggle;
                });
              },
              widget: Container(
                width: 140,
                height: 45,
                decoration: BoxDecoration(
                    border: Border.all(
                      color: Colors.pink,
                    ),
                    borderRadius: BorderRadius.circular(12)),
                child: Stack(
                  children: [
                    Row(
                      children: [
                        Container(
                          width: 69,
                          height: 45,
                          decoration: BoxDecoration(
                            borderRadius: BorderRadius.circular(12),
                            color: !isToggle ? Colors.pink : Colors.white,
                          ),
                        ),
                        Container(
                          width: 69,
                          height: 45,
                          decoration: BoxDecoration(
                            borderRadius: BorderRadius.circular(12),
                            color: isToggle ? Colors.pink : Colors.white,
                          ),
                        ),
                      ],
                    )
                  ],
                ),
              )),
          _widgetForm(
              onTap: () {
                setState(() {
                  if (colorsChanged > 2) {
                    colorsChanged = 0;
                  }
                  colorsChanged++;
                });
              },
              widget: Container(
                width: 150,
                height: 45,
                decoration: BoxDecoration(
                  borderRadius: BorderRadius.circular(30),
                  color: colorsChanged == 0
                      ? Colors.lightBlue
                      : colorsChanged == 1
                          ? Colors.deepOrange
                          : colorsChanged == 2
                              ? Colors.yellow
                              : Colors.cyan,
                ),
              )),
          _widgetForm(
              onTap: () {
                setState(() {
                  animatedCount++;
                });
              },
              widget: AnimatedSwitcher(
                duration: const Duration(milliseconds: 400),
                transitionBuilder: (Widget child, Animation<double> animation) {
                  return ScaleTransition(scale: animation, child: child);
                },
                child: Text(
                  animatedCount.toString(),
                  style: const TextStyle(fontSize: 30),
                  key: ValueKey<int>(animatedCount),
                ),
              )),
          _widgetForm(
            onTap: () {
              setState(() {
                textStyleChanged = !textStyleChanged;
              });
            },
            widget: AnimatedDefaultTextStyle(
                style: TextStyle(
                    color: !textStyleChanged ? Colors.red : Colors.white,
                    fontSize: 30,
                    fontWeight: FontWeight.bold),
                duration: const Duration(milliseconds: 1500),
                child: const Text('Flutter')),
          ),
          _widgetForm(
            onTap: () {
              setState(() {
                textStyleChanged = !textStyleChanged;
              });
            },
            widget: AnimatedDefaultTextStyle(
                style: TextStyle(
                    color: !textStyleChanged ? Colors.green : Colors.deepOrange,
                    fontSize: 30,
                    fontWeight: FontWeight.bold),
                duration: const Duration(milliseconds: 1500),
                child: const Text('Flutter')),
          ),
          _widgetForm(
              onTap: () {
                setState(() {
                  containerChanged = !containerChanged;
                });
              },
              widget: AnimatedContainer(
                duration: const Duration(milliseconds: 1500),
                width: !containerChanged ? 1 : 200,
                height: 45,
                decoration: BoxDecoration(
                    border: Border.all(
                        color: const Color.fromRGBO(215, 215, 215, 1)),
                    borderRadius: BorderRadius.circular(20),
                    color: Colors.green),
              )),
        ],
      ),
    );
  }

  Padding _widgetForm({
    required Widget widget,
    required Function() onTap,
  }) {
    return Padding(
      padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 20),
      child: Row(
        mainAxisAlignment: MainAxisAlignment.spaceBetween,
        children: [
          widget,
          InkWell(
            onTap: onTap,
            child: Container(
              width: 100,
              height: 45,
              decoration: BoxDecoration(
                  borderRadius: BorderRadius.circular(12), color: Colors.teal),
              child: const Center(
                  child: Text(
                'Click',
                style: TextStyle(color: Colors.white),
              )),
            ),
          ),
        ],
      ),
    );
  }
}

Example

profile
Flutter Developer

0개의 댓글