1. Introuction
현재까지 너무 많은 widget code가 main에 '쏠려'있는 것을 느꼈을 것이다. 그래서, 이번 lesson에선 추가적인 dart file을 만들어서 가독성을 높히는 방법을 찾아보도록 하자.
-lib
|-main.dart
|-start_screen.dart
|-question_screen.dart
|-quiz.dart
2. Quiz.dart
main에 MaterialApp을 담을 수 있는 class를 만들어보자. 우리는 Quiz라는 widget class를 만들려고 하며, 이 두개의 class는 아래와 같이 작성될 수 있다.
import 'package:adv_basics/question_screen.dart';
import 'package:flutter/material.dart';
import 'package:adv_basics/start_screen.dart';
class Quiz extends StatefulWidget{
const Quiz({super.key});
@override
State<Quiz> createState(){
return _QuizState();
}
}
class _QuizState extends State<Quiz>{
@override
Widget build(context){
return MaterialApp(
home: Scaffold(
body:Container(
decoration:BoxDecoration(
gradient:LinearGradient(
colors:[
Color.fromARGB(255, 89, 4, 138),
Color.fromARGB(255, 107, 15, 168)],
begin:Alignment.topLeft,
end:Alignment.bottomRight,
),
),
child: screenWidget,
))
);
}
}
✍️Note
- _QuizState class는 Quiz class의 파생 된 private class를 이다. build 함수를 오버로딩하여, main에서 지정한 MaterialApp을 모두 이전시킨다.
- Quiz class에서는 꼭 createState 함수를 정의 내린 뒤, 두번째 정의한 class를 return 한다.
3. question_screen.dart
question_screen.dart는 아래와 같은 형태로 임시적으로 만들고 싶다고 가정하자. (추후에 더 상세하게 수정할 예정임)
위 그림처럼 규격을 갖추기 위해선,Quiz.dart와 같은 StatefulWidget class를 선언할 필요가 있다.
import 'package:flutter/material.dart';
class QuestionScreen extends StatefulWidget{
const QuestionScreen({super.key});
@override
State<QuestionScreen>createState(){
return _QuestionsScreenState();
}
}
class _QuestionsScreenState extends State<QuestionScreen>{
@override
Widget build(context){
return SizedBox(
width:double.infinity,
child:Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
//child 01
Text(
"The questions are ...",
style:TextStyle(
color: Colors.white,
fontSize: 25,
)),
//child 02
const SizedBox(height:30),
//child 03
ElevatedButton(onPressed: (){}, child: Text("Answer01"),
),
const SizedBox(height:30),
//child 04
ElevatedButton(onPressed: (){}, child: Text("Answer02")),
const SizedBox(height:30),
//child05
ElevatedButton(onPressed: (){}, child: Text("Answer03"))
],)
);
}
}
4. Render Content Conditionally, Lifting State Up
import 'package:flutter/material.dart';
//Center enables the whole widget to fill the screen
class StartScreen extends StatelessWidget{
const StartScreen(this.startQuiz,{super.key});
@override
Widget build(context){
return Center(
child:Column(
//생략
//child 4
const SizedBox(height:30),
//the button to activate function
//<point1> 여기를 수정할 것!
OutlinedButton.icon(onPressed:StartScreen(),
//chiild is no loger used uner QutilineButton.icon; use label
label: const Text("Start Quiz"),
icon:const Icon(Icons.arrow_circle_right),
style:OutlinedButton.styleFrom(
foregroundColor:Colors.white,
),
)
],
)
);
}
}
quiz.dart를 보면, 우리가 처음으로 실행할 Widget은 StartScreen()이라는 것을 알 수 있다. 그러나, 우리가 button을 누르고 나면,wideget은 우리가 막 설정한 위 두 class widget으로 이동을 해야한다. 여기서 핵심은 초기화면 이후 다른 화면으로 전환되는 하나의 장치가 필요하다는 점이다.
4.1 Store switching widgets to a Temporary Widget
class _QuizState extends State<Quiz>{
var activeScreen="start-screen";
//a function for setting up state
void switchScreen(){
//anonymous function to swatich from StartScreen to QuestionScreen
setState(() {
activeScreen="questions-screen";
});
}
우리는 먼저 switchScreen이라는 void 함수를 만든다. 이 함수는 이름 자체에서 알 수 있듯이, 한 state에서 다른 state로 전환을 위한 도구로 작동한다. 그리고 그 함수 안에, State class에서 제공되는 setState를 이용해서 무익명 함수를 지정하고, activeScreen 변수가 자율적으로 변화되도록 허용한다.
switchScreen은 argument을 아무것도 받지 않는, void function임을 상기하자. 이 때, 이 switchScreen 함수는 StartScreen의 argument로 들어가게 된다. 그리고 현재, StartScreen 객체를 받아줄 widget 변수가 필요한데, 이를 screenWidget이라 칭하자.
class _QuizState extends State<Quiz>{
var activeScreen="start-screen";
//a function for setting up state
void switchScreen(){
//anonymous function to swatich from StartScreen to QuestionScreen
setState(() {
activeScreen="questions-screen";
if (activeScreen=="questions-screen"){
screenWidget=const QuestionScreen();
}
});
}
@override
Widget build(context){
// widget variable stroing screenWidget class
Widget screenWidget=StartScreen(switchScreen);
즉, QuizState 를 통해서 StartScreen을 호출하고, Start Screen은 switchScreen을 매개변수로 가지기 때문에,swtichcase가 호축된다.
이러한 방식으로 screen의 전환을 도모할 수 있다. 다만, 현재까지, StartScreen class는 아무런 매개변수를 가지고 있지 않도록 작성되었다. 이를 변경하기 위해선, 우리는 StartScreen의 constructor에 this.startQuiz(명칭은 아무렇게 바꿀 수 있음) 매개변수로 받을 수 있도록 허용하고, build method 아래에다가 startQuiz(void 함수)를 초기화시킨다.
//start_screen.dart
class StartScreen extends StatelessWidget{
const StartScreen(this.startQuiz,{super.key});
final void Function() startQuiz;
마지막으로, STartScreen class의 OutlinedButton.ico의 onPressed를 startQuiz로 변경한다.
아래는 fullcode이다.
import 'package:flutter/material.dart';
//Center enables the whole widget to fill the screen
class StartScreen extends StatelessWidget{
const StartScreen(this.startQuiz,{super.key});
final void Function() startQuiz;
@override
Widget build(context){
return Center(
child:Column(
mainAxisSize: MainAxisSize.min,
children: [
//child 0
//child 1
Opacity(opacity:0.6,
child:Image.asset(
"assets/images/quiz-logo.png",
width:300,
color: Color.fromARGB(221, 230, 211, 241),
)
),
//chidl 2
const SizedBox(height:80),
//child 3
const Text(
"Learn Flutter the fun way!",
style:TextStyle(
color:Colors.white,
fontSize:24),
),
//child 4
const SizedBox(height:30),
//the button to activate function
OutlinedButton.icon(onPressed:startQuiz,
//chiild is no loger used uner QutilineButton.icon; use label
label: const Text("Start Quiz"),
icon:const Icon(Icons.arrow_circle_right),
style:OutlinedButton.styleFrom(
foregroundColor:Colors.white,
),
)
],
)
);
}
}
'Front-End > Flutter' 카테고리의 다른 글
5. <Quiz APP>을 통한 Flutter Tutorial (0) | 2024.11.24 |
---|---|
4. <Quiz APP>을 통한 Flutter Tutorial: Modification to Current Style and Codes (0) | 2024.11.21 |
3. <Quiz APP>을 통한 project- Data model/ Dummy Data (0) | 2024.11.17 |
1. <Quiz APP>을 통한 Flutter Tutorial (0) | 2024.11.15 |