> Frontend/Flutter

Flutter_04. Rendering Contents conditionally

Janku 2023. 4. 19. 21:15

1. Reformat.

// quiz.dart contains contents MaterialApp
import 'package:basic101_01/components/questions_screen.dart';
import 'package:basic101_01/components/start_screen.dart';
import 'package:flutter/material.dart';

class Quiz extends StatefulWidget {
  const Quiz({super.key});

  @override
  State<Quiz> createState() {
    return _QuizState();
  }
}

class _QuizState extends State<Quiz> {
  Widget activeScreen = const StartScreen(); // able to store widgets in var
  void switchScreen() {
    setState(() {
      //QuestionScreen should follow StartScreen();
      activeScreen = const QuestionScreen();
    });
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: Container(
          decoration: const BoxDecoration(
            gradient: LinearGradient(
              colors: [
                Color.fromARGB(255, 78, 13, 151),
                Color.fromARGB(255, 107, 15, 168),
              ],
              begin: Alignment.topLeft,
              end: Alignment.bottomRight,
            ),
          ),
          child: activeScreen,
        ),
      ),
    );
  }
}

   - activeScreen이라는 var을 생성하여  추후에 버튼이 클릭시, StartScrenen Widget에서 QuestionScreen Widget으로 변경

 

<QuestionScreen Widget> 

// statefull widget

import 'package:flutter/material.dart';

class QuestionScreen extends StatefulWidget {
  const QuestionScreen({super.key});

  @override
  State<QuestionScreen> createState() {
    return _QuestionScreenState();
  }
}

class _QuestionScreenState extends State<QuestionScreen> {
  @override
  Widget build(BuildContext context) {
    return const Text('Question Screen');
  }
}

 

 

2. 버튼 연결

   - 순서 1. 화면을 변경해줄 switchScreen 이라는 변수는 quiz.dart에 있음으로, 해당 변수를 버튼이 있는 start_screen.dart로 전달

Widget activeScreen = const StartScreen(switchScreen); // able to store widgets in var
// switchScreen 에러 발생.
void switchScreen() {
  setState(() {
    //QuestionScreen should follow StartScreen();
    activeScreen = const QuestionScreen();
  });
}

   - 순서 2. start_screen.dart 에서 생성자에 this.startQuiz 등 원하는 변수명을 사용해 해당 변수를 받고, 선언

     :void Function() startQuiz를 받아만 왔고, 사용하기 위해 변수로 선언하지 않았기에,final void Function() startQuiz; 선언하고,          생성자와 연결 

const StartScreen(this.startQuiz, {super.key}); // add positional argument
// able to call switchScreen because it was passed

final void Function() startQuiz;

 

   - 순서 3. 동일한 화면내에서, 버튼이 클릭될 경우, 함수 변수 startQuiz 가 실행되도록 포인터 연결

 

onPressed: startQuiz, // anonymous function

   - 순서 4.  다시 quiz.dart로 이동하면, 해당 부분이 에러남 (추가적으로, 아래 4번에서 추가 방법 설명 예정)

     : 원인: switchScreen값이 초기화 되기전에 사용되기 떄문.

     : 해결: void initState(){} 를 선언하여, build()가 실행되전에, 변수 할당

Widget activeScreen = StartScreen(switchScreen)

 

class _QuizState extends State<Quiz> {
  Widget? activeScreen; // able to store widgets in var
  // error because using switchScreen when initializing the activeScreen variable at the same point of time.

  @override
  void initState() {
    // initState will execute once after the object has been created
    // this does not excute at all at this time, so no need to use setState
    activeScreen = StartScreen(switchScreen);
    super.initState();
  }

 

 

3.Life-cycle in Flutter Widget.

   - Every Flutter Widget has a built-in lifecycle: A collection of methods that are automatically executed by Flutter

   - 3 가지 중요 Life-Cycle 이 있음

     : 1. initState() : 처음 StatefulWidget's State가 init 될 때, 실행

     : 2. build(): 처음 빌드 된 경우 실행되고, setState가 실행된 후 실행

     : 3. dispose(): Widget 이 버려진 후 실행

 

4.  2-4 변경

   - 기존의 방법을 ternary expression 으로 변경 할 수 있다. 

// 방법 1.
// Widget? activeScreen; // able to store widgets in var
// error because using switchScreen when initializing the activeScreen variable at the same point of time.

// @override
// void initState() {
//   // initState will execute once after the object has been created
//   // this does not excute at all at this time, so no need to use setState
//   activeScreen = StartScreen(switchScreen);
//   super.initState();
// }

// void switchScreen() {
//   setState(() {
//     //QuestionScreen should follow StartScreen();
//     activeScreen = const QuestionScreen();
//   });
// }

// 방법 2.
var activeScreen = 'start-screen';

void switchScreen() {
  setState(() {
    //QuestionScreen should follow StartScreen();
    activeScreen = 'questions-screen';
  });
}

   - 기존 activeScreen 에서 아래처럼 변경 

// 방법 1
// child: activeScreen,
// 방법 2: ternary expression
child: activeScreen == 'start-screen'
    ? StartScreen(switchScreen)
    : const QuestionScreen(),