Flutter_04. Rendering Contents conditionally
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(),