- pubspec.yaml 에 http: ^0.13.4 추가 후 pub get 누르기
| dependencies: |
| http: ^0.13.4 |
- main.dart 파일 들어가서 코드 추가
| import 'package:http/http.dart' as http; |
| import 'dart:convert'; |
- dart:convert 이건 JSON -> 일반자료형 변환을 도와주는 함수모음집
- android/app/src/main/AndroidManifest.xml
<uses-permission android:name="android.permission.INTERNET" />
- await http.get( Uri.parse('요청할url') ) 사용하여 GET 요청 날리기
→ 변수에 저장해서 사용
| getData() async { |
| var result = await http.get( Uri.parse('https://codingapple1.github.io/app/data.json') ); |
| print( jsonDecode(result.body) ) |
| } |
⇒ 가져온 데이터는 JSON 형식
- 서버랑 주고 받는 데이터는 문자만 가능
- JSON을 그대로 사용해도 되나 조작하기 십도록 list, map 자료로 변환 → json.Decode()
- reuslt = [{”name”:”jhon”, “age”:20}, {”name”:”hong”, “age”:15}]에서 20을 가져오고 싶다면 result[0][”age”] 하면 20이 출력됨
- 에러 체크하고 싶으면 result.statusCode를 출력하여 성공 여부 확인
| getData() async { |
| var result = await http.get( |
| Uri.parse('https://codingapple1.github.io/app/data.json') |
| ); |
| if (result.statusCode == 200) { |
| print( jsonDecode(result.body) ); |
| } else { |
| throw Exception('실패함'); |
| } |
| } |
| @override |
| void initState() { |
| super.initState(); |
| getData(); |
| } |
- 자주 바뀌는 데이터인 경우 state에 저장해서 사용
| class _MyAppState extends State<MyApp> { |
| var tab = 0; |
| var data = []; |
| |
| getData() async { |
| var result = await http.get(Uri.parse('https://codingapple1.github.io/app/data.json')); |
| var result2 = jsonDecode(result.body); |
| setState((){ |
| data = result2; |
| }) |
| } |
| |
| (생략) |
- MyApp 안에있던 Home 에 전송하고
Home(data : data)
- Home 은 등록하고
| class Home extends StatelessWidget{ |
| const Home ({Key? key, this.data}) |
| final data; |
- Home 안에서 사용
Text(data[0]['content'])
⇒ 문제점 : 데이터 도착 전에 먼저 쓰면 에러 발생
- if문 사용하여 null check
- .inNotEmpty 사용하면 됨
| class Home extends StatelessWidget{ |
| const Home ({Key? key, this.data}) |
| final data; |
| Widget build(BuildContext context){ |
| |
| if (data.isNotEmpty){ |
| return ListView.builder(생략); |
| } else { |
| return Text('로딩중'); |
| } |
| |
| } |
| } |
→ CircularProgressIndicator() 위젯 사용하면 로딩 중인 표시로 표현됨
→ 아니면 Dio 패키지 설치하여 사용해도 됨
→ 아니면 FutureBuilder 사용
- 입력한 Future 변수가 실제 데이터로 변할 때 내부 코드 1회 실행해주는 위젯
- future: 안에는 Future를 담은 state 이름을 적으면 됨
- http.get() 이런거 직접 적어도 되긴 하지만 state에 저장했다가 쓰는게 좋음
- builder: (){return 어쩌구} 안의 코드는 입력한 state 데이터가 도착할 때 실행
- 그리고 snapshot 이라는 파라미터가 변화된 state 데이터를 의미
- ⇒ 도착 시 위젯을 보여줘야할 경우 FutureBuilder가 유용하지만 데이터가 자주 추가되는 경우엔 불편
| FutureBuilder ( |
| future: http.get(어쩌구), |
| builder: (context, snapshot) { |
| if (snapshot.hasData) { |
| return Text('post에 데이터 있으면 보여줄 위젯') |
| } |
| return Text('post에 데이터 없으면 보여줄 위젯') |
| }, |
| ) |
| import 'package:flutter/material.dart'; |
| import './style.dart' as style; |
| import 'package:http/http.dart' as http; |
| import 'dart:convert'; |
| |
| void main() { |
| runApp( |
| MaterialApp( |
| theme: style.theme, |
| home: MyApp() |
| )); |
| } |
| |
| class MyApp extends StatefulWidget { |
| const MyApp({Key? key}) : super(key: key); |
| |
| @override |
| State<MyApp> createState() => _MyAppState(); |
| } |
| |
| class _MyAppState extends State<MyApp> { |
| var tab = 0; |
| var list = [1, 2, 3]; |
| var map = {'name':'john', 'age':20}; |
| var data = []; |
| |
| getData() async { |
| var result = await http.get(Uri.parse('https://codingapple1.github.io/app/data.json')); |
| var result2 = jsonDecode(result.body); |
| setState(() { |
| data = result2; |
| }); |
| |
| print(result2[0]['likes']); |
| } |
| |
| @override |
| void initState() { |
| super.initState(); |
| getData(); |
| } |
| |
| @override |
| Widget build(BuildContext context) { |
| return Scaffold( |
| appBar: AppBar( |
| title: Text('Instagram'), |
| actions: [ |
| IconButton( |
| icon: Icon(Icons.add_box_outlined), |
| onPressed: () {}, |
| iconSize: 30, |
| ) |
| ]), |
| body: [Home(data : data), Text('샵페이지')][tab], |
| bottomNavigationBar: BottomNavigationBar( |
| showSelectedLabels: false, |
| showUnselectedLabels: false, |
| onTap: (i){ |
| setState(() { |
| tab = i; |
| }); |
| }, |
| items: [ |
| BottomNavigationBarItem(icon: Icon(Icons.home_outlined), label: '홈'), |
| BottomNavigationBarItem(icon: Icon(Icons.shopping_bag_outlined), label: '샵') |
| ], |
| ), |
| ); |
| } |
| } |
| |
| class Home extends StatelessWidget { |
| const Home({Key? key, this.data}) : super(key: key); |
| final data; |
| |
| @override |
| Widget build(BuildContext context) { |
| return ListView.builder( |
| itemCount: 3, |
| itemBuilder: (c, i) { |
| return Column( |
| crossAxisAlignment: CrossAxisAlignment.start, |
| children: [ |
| Image.network(data[i]['image']), |
| Container( |
| constraints: BoxConstraints(maxWidth: 600), |
| padding: EdgeInsets.all(20), |
| width: double.infinity, |
| child: Column( |
| children: [ |
| Text(data[i]['likes'].toString()), |
| Text(data[i]['user']), |
| Text(data[i]['content']) |
| ], |
| ), |
| ) |
| ], |
| ); |
| } |
| ); |
| } |
| } |