[flutter] flutter 5 (StatefulWidget)

허성재's avatar
Oct 11, 2024
[flutter] flutter 5 (StatefulWidget)
 
StatelessWidget만 만들다가 StatefulWidget에 대해 배웠다.
StatefulWidget을 쓰면 setState(){} 를 사용할수 있다. 해당 Widget을 새로 빌드한다.
 
아래의 예제는 StatefulWidget 에 int num =1 을 넣어 상태를 저장하고 이것을 변경할때마다 Widget을 다시 빌드함으로써 변경된 상태를 나타낼수 있다.
import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter/widgets.dart'; void main() { runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return MaterialApp( debugShowCheckedModeBanner: false, home: HomePage(), ); } } class HomePage extends StatefulWidget { @override State<HomePage> createState() => _HomePageState(); } class _HomePageState extends State<HomePage> { int num = 1; @override Widget build(BuildContext context) { print("나그려짐"); return Container( color: Colors.yellow, child: Padding( padding: const EdgeInsets.all(20.0), child: Column( children: [ Expanded( child: Container( color: Colors.red, child: Align( child: Text( "${num}", style: TextStyle( color: Colors.white, fontWeight: FontWeight.bold, fontSize: 100, decoration: TextDecoration.none), ), ), ), ), Expanded( child: Container( color: Colors.blue, child: Align( child: ElevatedButton( style: ElevatedButton.styleFrom(backgroundColor: Colors.red), onPressed: () { num++; setState(() {}); }, child: Text( "증가", style: TextStyle( color: Colors.white, fontWeight: FontWeight.bold, fontSize: 100, ), ), ), ), ), ), ], ), ), ); } }
여기서 문제점은 setState를 호출할떄마다 전체의 화면이 다 다시 그려진다.
컨텍스트 분리하지않으면 전체가 다시 그려짐 context를 분리하자.
import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter/widgets.dart'; void main() { runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return MaterialApp( debugShowCheckedModeBanner: false, home: HomePage(), ); } } class HomePage extends StatefulWidget { @override State<HomePage> createState() => _HomePageState(); } class _HomePageState extends State<HomePage> { // 1. 상태 int num = 1; // 2. 행위 void add(){ num++; setState(() {}); } @override Widget build(BuildContext context) { print("나그려짐"); return Container( color: Colors.yellow, child: Padding( padding: const EdgeInsets.all(20.0), child: Column( children: [ Header(num: num), Bottom(add: add), ], ), ), ); } } class Bottom extends StatelessWidget { final add; Bottom({required this.add}); @override Widget build(BuildContext context) { print("Bottom 다시 그려짐"); return Expanded( child: Container( color: Colors.blue, child: Align( child: ElevatedButton( style: ElevatedButton.styleFrom(backgroundColor: Colors.red), onPressed: () { add(); }, child: Text( "증가", style: TextStyle( color: Colors.white, fontWeight: FontWeight.bold, fontSize: 100, ), ), ), ), ), ); } } class Header extends StatelessWidget { const Header({ super.key, required this.num, }); final int num; @override Widget build(BuildContext context) { print("Header 다시 그려짐"); return Expanded( child: Container( color: Colors.red, child: Align( child: Text( "${num}", style: TextStyle( color: Colors.white, fontWeight: FontWeight.bold, fontSize: 100, decoration: TextDecoration.none), ), ), ), ); } }
 
컨텍스트를 분리하여 상태가 변경되는 부분만 sf로 만든다.
상태와 행위를 header에 넣으면 bottom은 다시 안그려도된다
import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter/widgets.dart'; void main() { runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return MaterialApp( debugShowCheckedModeBanner: false, home: HomePage(), ); } } class HomePage extends StatelessWidget { const HomePage({super.key}); @override Widget build(BuildContext context) { print("HomePage 다시 그려짐"); return Container( color: Colors.yellow, child: Padding( padding: const EdgeInsets.all(20.0), child: Column( children: [ Header(), Bottom(), ], ), ), ); } } class Bottom extends StatelessWidget { @override Widget build(BuildContext context) { print("Bottom 다시 그려짐"); return Expanded( child: Container( color: Colors.blue, ), ); } } class Header extends StatefulWidget { @override State<Header> createState() => _HeaderState(); } class _HeaderState extends State<Header> { int num = 1; void add() { num++; setState(() {}); } @override Widget build(BuildContext context) { print("Header 다시 그려짐"); return Expanded( child: Container( color: Colors.red, child: Align( child: Column( children: [ Text( "${num}", style: TextStyle( color: Colors.white, fontWeight: FontWeight.bold, fontSize: 100, decoration: TextDecoration.none), ), ElevatedButton( onPressed: () { add(); }, child: Text("증가")) ], ), ), ), ); } }
 
그림을 그리다보면, 상태의 화면과 행위의 화면이 다를때 가장 가까운 공통부모를 sf로 두고 상태와 행위를 전달한다
 
 
 
Share article

heo-gom