[플러터] 스위치 달아서 화면 갱신하기

ho's·2022년 8월 10일
0

Do it flutter!

내용을 정리하면서 익혀보자!

버튼의 모양을 만들어 보자.

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  var switchValue = false;
  
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),

      darkTheme: ThemeData.light(),
      home: Scaffold(
        body: Center(
          child: Switch(
            value: switchValue,
            onChanged: (value) {
              switchValue = value;
            },
          )
        )
      )
    );
  }
}

버튼을 눌러도 왜 눌리지 않을까?

현재 StatelessWidget을 상속받은 MyApp 클래스에서 Scaffold를 이용해 스위치를 구성했다.
이 스위치는 사용자가 누를 때마다 true나 false값이 switchValue값으로 들어가 스위치 상태가 변한다.
그런데 실행된 앱에서 스위치를 눌러도 변화가 없다.
MyApp 클래스는 StatelessWidget을 상속받아 만들었으므로 위젯의 상태 변경에 따른 값을 화면에 반영하지 못하기 때문이다.

StatefulWidget으로 바꾸기

import 'package:flutter/material.dart';

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

class MyApp extends StatefulWidget {
  
  State<StatefulWidget> createState(){
    return _MyApp();
  }
}

class _MyApp extends State<MyApp>{
  var switchValue = false;
  
  Widget build(BuildContext context) {
    return MaterialApp(
        title: 'Flutter Demo',
        theme: ThemeData(
          primarySwatch: Colors.blue,
          visualDensity: VisualDensity.adaptivePlatformDensity,
        ),
        darkTheme: ThemeData.light(),
        home: Scaffold(
            body: Center(
                child: Switch(
                  value: switchValue,
                  onChanged: (value) {
                    print(value);
                    switchValue = value;
                  },
                )
            )
        )
    );
  }
}

코드해석

  • 스테이트풀 위젯은 혼자서 화면을 출력할 수 없고, State클래스가 필요
  • State클래스를 상속받는 _MyApp클래스를 만들고 그 안에서 앞에서 만들어 놓은 위젯을 담는다.
  • StatefulWidget클래스를 상속받은 MyApp은 createState() 함수를 재정의해서 호출
  • MyApp클래스가 현재 화면을 주시하다가 상태가 변경되면 이를 감지하고 _MyApp클래스가 화면을 갱신

_(언더 스코어)는 내부에서만 사용할 수 있다는 것을 의미한다. _MyApp 클래스는 main.dart 안에서만 사용하므로 언더스코어를 넣는다.

StatefulWidget으로 바꾸어도 해결되지 않는 이유는?

  • 위와 같이 StatefulWidget으로 작성을 해도, 버튼을 눌렀을때 바뀌지가 않는다.
    그 이유는 플러터에서는 변숫값이 바꾸면 이 사실을 앱에 알려 화면을 갱신해야 하기 때문이다.
    이때 사용하는 함수가 setState()이다.
child: Switch(
                  value: switchValue,
                  onChanged: (value) {
                    setState(() {
                      print(value);
                      switchValue = value;
                    });
                  }),                

해결이 되었다.
이처럼 화면의 값을 바꾸려면 setState() 함수 안에서 해야 한다. 그래야만 바뀐 값이 반영된 화면으로 갱신한다.

버튼을 눌러 텍스트를 바꾸기

import 'package:flutter/material.dart';

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

class MyApp extends StatefulWidget {
  
  State<StatefulWidget> createState(){
    return _MyApp();
  }
}

class _MyApp extends State<MyApp>{
  var switchValue = false;
  String test = 'hello';
  
  Widget build(BuildContext context) {
    return MaterialApp(
        title: 'Flutter Demo',
        theme: ThemeData(
          primarySwatch: Colors.blue,
          visualDensity: VisualDensity.adaptivePlatformDensity,
        ),
        darkTheme: ThemeData.light(),
        home: Scaffold(
            body: Center(
                child: RaisedButton(
                  child: Text('$test'),
                  onPressed: () {},
                )
            )
        )
    );
  }
}
  • 버튼 위젯에도 child를 선언할 수 있다.
  • child를 선언해 Text를 넣고 그 Text에 문자열 'hello'가 입력된 test변수를 대입한다.
  • Text는 따옴표 안에 $기호 다음을 변수로 인식한다.

버튼을 누르면 텍스트가 바뀌는 로직 추가

child: RaisedButton(
                  child: Text('$test'),
                  onPressed: () {
                    if(test == 'hello'){
                      setState(() {
                        test = 'flutter';
                      });
                    }else {
                      setState(() {
                        test = 'hello';
                      });
                    }
                  })

위의 코드를 추가하면 아래와 같이 버튼을 클릭하면 text가 바뀐다.


색을 바꾸어 보자!

  1. _MyApp 위젯에 color변수 추가하기
Color _color = Colors.blue;
  1. RaisedButton 위젯에 color 변수를 추가해서 if문에 조건 넣기
body: Center(
                child: RaisedButton(
                  child: Text('$test'),
                  color: _color,
                  onPressed: () {
                    if(_color == Colors.blue){
                      setState(() {
                        test = 'flutter';
                        _color = Colors.amber;
                      });
                    }else {
                      setState(() {
                        test = 'hello';
                        _color = Colors.blue;
                      });
                    }
                  },
                )
            )

profile
그래야만 한다

0개의 댓글