카테고리 없음
6주차 주간과제
신승호.
2023. 3. 5. 23:19
- 아래는 공개된 API의 리스트를 공유하는 Github 문서이다. 아래의 링크에 들어가서, 공개되어있는 API중 하나를 분석하고 직접 기획하여 본인이 기획한 어플을 제작하시오.
- 기획 과제내용을 간단히 2-3줄로 설명하여 제출하시오. 이 때 해결 과정을 함께 포함하여 정리하시오. (어려웠던 내용과 헤맸던 내용이 있다면 반드시 기재할 것)
- 다음의 조건을 반드시 만족할 것.
- 페이지는 두 페이지 이상이어야 하며 네비게이션을 활용하여 페이지 이동이 포함될 것
- 클래스를 작성하여 Serialization이 적용될 수 있도록 할 것
- 적절한 애니메이션 효과를 포함할 것
API를 고르는데 뭐가 뭔지 모르겠고.. 그래도 스포츠앱을 만들어 보고 싶어서 찾아봤는데 키가 있어야하고.. 해리포터 API가 JSON이 쉽게 바로 나와서 해리포터 API를 골랐다.
all characters: 전체 등장인물
https://hp-api.onrender.com/api/characters
characters who are Hogwarts students during the book series: 호그와트 학생
https://hp-api.onrender.com/api/characters/students
characters who are Hogwarts staff during the book series: 호그와트 직원
https://hp-api.onrender.com/api/characters/staff
characters in a certain house, e.g. /gryffindor: 등장인물 기숙사
https://hp-api.onrender.com/api/characters/house/:house
all spells: 마법주문
https://hp-api.onrender.com/api/spells
이런 예제도 나와있어서 비슷하게 만들어보고싶다.
아직 이해를 못했나봅니다 제가..
import 'package:harrypoter_app/model/wand.dart';
class Character {
String id;
String name;
List<String>? alternate_names;
String species;
String gender;
String? house;
DateTime? dateOfBirth;
String? yearOfBirth;
bool wizard;
String? ancestry;
String? eyeColour;
String hairColour;
Wand wand;
String? patronus;
bool hogwartsStudent;
bool hogwartsStaff;
String? actor;
List<String>? alternate_actors;
bool alive;
String? image;
Character({
required this.id,
required this.name,
required this.alternate_names,
required this.species,
required this.gender,
required this.house,
required this.dateOfBirth,
required this.yearOfBirth,
required this.wizard,
required this.ancestry,
required this.eyeColour,
required this.hairColour,
required this.wand,
required this.patronus,
required this.hogwartsStudent,
required this.hogwartsStaff,
required this.actor,
required this.alternate_actors,
required this.alive,
required this.image,
});
factory Character.fromMap(Map<String, dynamic> map) {
return Character(
id: map['id'],
name: map['name'],
alternate_names: map['alternate_names'] != null
? List<String>.from(map['alternate_names'])
: null,
species: map['species'],
gender: map['gender'],
house: map['house'],
dateOfBirth: map['dateOfBirth'],
yearOfBirth: map['yearOfBirth'],
wizard: map['wizard'],
ancestry: map['ancestry'],
eyeColour: map['eyeColour'],
hairColour: map['hairColour'],
wand: Wand.fromMap(map['wand']) ,
patronus: map['patronus'],
hogwartsStudent: map['hogwartsStudent'],
hogwartsStaff: map['hogwartsStaff'],
actor: map['actor'],
alternate_actors: map['alternate_names'] != null
? List<String>.from(map['alternate_actors'])
: null,
alive: map['alive'],
image: map['image']);
}
}
등장인물 JSON에 있는 타입은 다 넣었고 null일 수도 있는것들을 nullsafety처리
lib/model/wand.dart
class Wand {
String? wood;
String? core;
int? length;
Wand({required this.wood, required this.core, required this.length});
factory Wand.fromMap(Map<String, dynamic> map) {
return Wand(wood: map['wood'], core: map['core'], length: map['length']);
}
}
main.dart
import 'package:flutter/material.dart';
import 'package:harrypoter_app/page/mainpage.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData.dark(),
home: MainPage(),
);
}
}
lib/page/mainpage.dart
여기부터 테스트하면서 해보려고 일단 대충만들어놓음
import 'package:flutter/material.dart';
import 'package:harrypoter_app/page/spellpage.dart';
import 'package:harrypoter_app/page/staffpage.dart';
import 'package:harrypoter_app/page/studentpage.dart';
class MainPage extends StatefulWidget {
const MainPage({super.key});
@override
State<MainPage> createState() => _MainPageState();
}
class _MainPageState extends State<MainPage> {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
alignment: Alignment.center,
decoration: BoxDecoration(
image: DecorationImage(
fit: BoxFit.cover,
colorFilter: ColorFilter.mode(Colors.black38, BlendMode.darken),
image: NetworkImage(
'https://images.christiandaily.co.kr/data/images/full/68175/image.jpg?w=600'))),
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ListTile(
onTap: () {
Navigator.push(context,
MaterialPageRoute(builder: ((context) {
return StudentPage();
})));
},
tileColor: Colors.white,
title: Text('호그와트 학생'),
subtitle: Text('명단보기'),
),
ListTile(
onTap: () {
Navigator.push(context,
MaterialPageRoute(builder: ((context) {
return StaffPage();
})));
},
tileColor: Colors.white,
title: Text('호그와트 직원'),
subtitle: Text('명단보기'),
),
ListTile(
onTap: () {
Navigator.push(context,
MaterialPageRoute(builder: ((context) {
return SpellPage();
})));
},
tileColor: Colors.white,
title: Text('호그와트 마법주문'),
subtitle: Text('윙가르디움 레비오사~'),
),
],
),
),
),
);
}
}
spell.dart
class Spell {
String id;
String name;
String descriprion;
Spell({required this.id, required this.name, required this.descriprion});
factory Spell.fromMap(Map<String, dynamic> map) {
return Spell(
id: map['id'], name: map['name'], descriprion: map['descriprion']);
}
}
SpellPage.dart
// ignore_for_file: prefer_const_constructors
import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:harrypoter_app/model/spell.dart';
class SpellPage extends StatefulWidget {
const SpellPage({super.key});
@override
State<SpellPage> createState() => _SpellPageState();
}
class _SpellPageState extends State<SpellPage> {
List<Spell> spell = [];
Dio dio = Dio();
var url = 'https://hp-api.onrender.com/api/spells';
readData() async {
var res = await dio.get(url);
if (res.statusCode == 200) {
var magic = List<Map<String, dynamic>>.from(res.data);
setState(() => spell = magic.map((e) => Spell.fromMap(e)).toList());
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
centerTitle: true,
backgroundColor: Colors.transparent,
elevation: 0,
title: Text(
'Spell',
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 30),
),
),
body: ListView.builder(
itemCount: spell.length,
itemBuilder: ((context, index) {
return ListTile(
title: Text(spell[index].name),
subtitle: Text(spell[index].descriprion),
);
})));
}
}
일단 SpellPage부터 막혔다. ListTile형태로 스크롤하면서 내리려고 했는데..
아무것도 뜨지않음;
StaffPage.dart
// ignore_for_file: prefer_const_constructors
import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:harrypoter_app/model/character.dart';
class StaffPage extends StatefulWidget {
const StaffPage({super.key});
@override
State<StaffPage> createState() => _StaffPageState();
}
class _StaffPageState extends State<StaffPage> {
List<Character> staffs = [];
Dio dio = Dio();
var url = 'https://hp-api.onrender.com/api/characters/staff';
readData() async {
var res = await dio.get(url);
if (res.statusCode == 200) {
var staff = List<Map<String, dynamic>>.from(res.data);
setState(() => staffs = staff.map((e) => Character.fromMap(e)).toList());
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
centerTitle: true,
title: Text(
'Staff',
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 30),
),
backgroundColor: Colors.transparent,
elevation: 0,
),
body: Container(
alignment: Alignment.center,
decoration: BoxDecoration(
image: DecorationImage(
fit: BoxFit.cover,
colorFilter:
ColorFilter.mode(Colors.black38, BlendMode.darken),
image: NetworkImage(
'https://mblogthumb-phinf.pstatic.net/20110728_125/eponine77_1311816657845yd7Co_JPEG/67900_S45_130538.jpg?type=w2'))),
child: PageView.builder(
itemCount: staffs.length,
itemBuilder: ((context, index) {
return Center(child: Image.network(staffs[index].image!));
}))),
);
}
}
lib/page/studentpage.dart
// ignore_for_file: prefer_const_constructors
import 'package:flutter/material.dart';
import 'package:flutter/src/widgets/container.dart';
import 'package:flutter/src/widgets/framework.dart';
class StudentPage extends StatefulWidget {
const StudentPage({super.key});
@override
State<StudentPage> createState() => _StudentPageState();
}
class _StudentPageState extends State<StudentPage> {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Text('학생페이지'),
),
);
}
}
dio부분 강의를 다시 들어보겠습니다..
class부분은 맞는지 알고싶습니다.