> Frontend/Flutter

Flutter_20230414_02. StatefulWidget

Janku 2023. 4. 17. 20:09

1. Column() widget and Row() widget:

- 예제:

child: Center(
  child: Column(
    children: [
      Image.asset('assets/images/dice-2.png', width: 200),
      TextButton(onPressed: rollDice, child: const Text('Roll Dice'))
    ],
  ),
),

 

2. 해당 widget은 StatelessWidget이기 때문에, 이런식으로 internally changing data 불가.

class GradientContainer extends StatelessWidget {
var activeDiceImage = 'assets/images/dice-2.png';


void rollDice() {
  activeDiceImage = 'assets/images/dice-4.png';
}

 

 

3. StatefulWidget을 사용하여, 문제해결. 

   : StatefulWidget - 변경 가능한 상태(State)를 가진 widget. 

   : 여기서의 State은 widget이 빌드될때 동기적으로 읽을 수 있고, 생명주기동안 변경될 수 있는 정보.

   - StatefulWidget 인 DiceRoller는 createState()를 통해 같은 파일내, private 클래스인 _DiceRoller라는 객체를 리턴

   - setState() 함수는 build 함수 재실행

 

import 'package:flutter/material.dart';

// Public Class
class DiceRoller extends StatefulWidget {
  // Constructor
  const DiceRoller({super.key});
  @override
  State<DiceRoller> createState() {
    //generic Type임.
    return _DiceRollerState();
  }
}

// Private Class
class _DiceRollerState extends State<DiceRoller> {
  var activeDiceImage = 'assets/images/dice-2.png';
  void rollDice() {
    setState(()=>{ // tell Flutter to re-execute build.
      activeDiceImage
    });
    activeDiceImage = 'assets/images/dice-4.png';
  }
  @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisSize: MainAxisSize.min,
      children: [
        Image.asset(activeDiceImage, width: 200),
        TextButton(onPressed: rollDice, child: const Text('Roll Dice')),
      ],
    );
  }
}

 

 

4. 코드 정리 (EP.50)

 

import 'dart:math';
import 'package:flutter/material.dart';

final randomizer = Random();

// Public Class
class DiceRoller extends StatefulWidget {
  // Constructor
  const DiceRoller({super.key});

  @override
  State<DiceRoller> createState() {
    //generic Type임.
    return _DiceRollerState();
  }
}

// Private Class
class _DiceRollerState extends State<DiceRoller> {
  var currentDiceRoll = 1;

  void rollDice() {
    currentDiceRoll = randomizer.nextInt(6) + 1;
    setState(() => {
          // tell Flutter to re-execute build.
          currentDiceRoll
        });
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisSize: MainAxisSize.min,
      children: [
        Image.asset('assets/images/dice-$currentDiceRoll.png', width: 200),
        TextButton(onPressed: rollDice, child: const Text('Roll Dice')),
      ],
    );
  }
}