pub.dev에서 http
패키지 다운
URL생성
생성한 URL을 사용하여 http get요청을 보냄
http응답에서 받은 데이터를 JSON형식으로 디코딩하여 변수에 저장
객체로 변환하여 반환
배열로 받기위해서는 객체를 배열에 for문으로 add
import 'dart:convert';
import 'package:http/http.dart' as http; //http요청을 도와주는 패키지를 http로 명시
import 'package:webtoon/models/webtoon_model.dart';
class ApiService {
final String baseUrl = "https://webtoon-crawler.nomadcoders.workers.dev";
final String today = "today";
Future<List<WebtoonModel>> getTodaysToons() async {
List<WebtoonModel> webtoonInstances = [];
final url = Uri.parse("$baseUrl/$today"); //URL을 생성
final response = await http.get(url); //생성한 URL을 사용하여 http get요청을 보냄
if (response.statusCode == 200) {
final List<dynamic> webtoons = jsonDecode(response.body); //http응답에서 받은 데이터를 JSON형식으로 디코딩하여 변수명으로 저장
for (var webtoon in webtoons) {
webtoonInstances.add(WebtoonModel.fromJson(webtoon));
//fromJson이라는 named constructor을 사용해서 webtoonModel을 만들어준다
}
return webtoonInstances;
}
throw Error();
}
}
//named constructor
//constructor의 인수만 적어주고, property를 적어주면 초기화할 수 있어서 편리
class WebtoonModel {
final String title, thumb, id;
WebtoonModel.fromJson(Map<String, dynamic> json)
: title = json["title"],
thumb = json["thumb"],
id = json["id"];
}
statefuleWidget
을 사용해서
비동기처리 api,setstate,isLoading을 처리할 수 있다
class HomeScreen extends StatefulWidget {
const HomeScreen({super.key});
State<HomeScreen> createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
List<WebtoonModel> webtoons = [];
bool isLoading = true;
void waitForWebToons() async {
webtoons = await ApiService.getTodaysToons();
isLoading = false;
setState(() {});
}
void initState() {
//빌드를 하기 전에 먼저 실행(lifecycle)
super.initState();
waitForWebToons();
}
Widget build(BuildContext context) {
}
FutureBuilder
FutureBuilder를 사용하면 stateless 위젯으로 비동기처리 api를 가져올 수 있어요~!
await,setstate,isLoading을 한번에 해결해주는 위젯
spanshot을 이용하면 future의 상태를 알수있다
futureBuilder는 future랑 builder()를 받는다
future-> 기다릴 Future를 작성
builder함수-> context와 snapshot을 전달받는다
(*스냅샷은 future의 상태를 알수있다)
listView
여러항목을 나열하는데 최적화된 widget
listView.builder
인덱스를 통해 어떤 아이템이 build되는지 알 수 있다
사용자가 보고 있는 아이템만 build해줄수있다(메모리효율을 높여준다)
final Future<List<WebtoonModel>> webtoons = ApiService.getTodaysToons()
body: FutureBuilder(
future: webtoons,
builder: (context, snapshot) {
if (snapshot.hasData) {
return ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: snapshot.data!.length,
itemBuilder: (context, index) {
var webtoon = snapshot.data![index];
return Text(webtoon.title);
},
);
}
return const Center(
child: CircularProgressIndicator(), //로딩처리
);
},
),
statefulwidget은 생성자가 호출될때, widget 속성에 해당 statefulwidget의 현재 상태가 자동으로 저장되기때문에 위젯을 통해 state에 접근할 수 있다
class DetailScreen extends StatefulWidget {
final String title, thumb, id;
const DetailScreen({
super.key,
required this.title,
required this.thumb,
required this.id,
});
State<DetailScreen> createState() => _DetailScreenState();
}
class _DetailScreenState extends State<DetailScreen> {
late Future<WebtoonDetailModel> webtoon;
void initState() {
super.initState();
webtoon = ApiService.getToonById(widget.id);
}
statelesswidget을 사용하면 객체를 생성하는 생성자 역할을 하지 않기 대문에 퍼로퍼티 초기화를 시킬 수 없다
대신, late
키워드를 사용하여 변수를 선언할때 초기화하지 않고, 나중에 값이 필요할때 값을 할당할 수 있다
class DetailScreen extends StatelessWidget {
final String title, thumb, id;
late final webtoon=ApiService.getToonById(id);
DetailScreen({
super.key,
required this.title,
required this.thumb,
required this.id,
});