สำหรับบทเรียนรู้นี้เป็นการสร้าง API Provider สำหรับการเรียก API เพื่อนำข้อมูลมาแสดงที่ List View สำหรับตัวอย่างการใช้งาน แต่ก่อนอื่นให้ทำการติดตั้ง package เพิ่มเติมก่อนคือ
http: any
intl: any
html2md: any
flutter_markdown: any
โดยเปิดไฟล์ pubspec.yaml จากนั้นเพิ่ม package ลักษณะดังนี้
dependencies:
flutter:
sdk: flutter
# The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^0.1.2
splashscreen: any
http: any
intl: any
html2md: any
flutter_markdown: any
สร้าง Class API Provider
lib/api_provider.dart
import 'package:http/http.dart' as http;
class ApiProvider {
ApiProvider();
String apiUrl = 'https://api.yourdomain.com/v1';
Future<http.Response> getPost() async {
return await http.get('$apiUrl/post');
}
Future<http.Response> getPostView(int id) async {
return await http.get('$apiUrl/post/$id');
}
}
มี 2 method ที่สร้างเพื่อเรียก API นั่นคือ getPost() โดยจะเรียกรายการ Post ทั้งหมด และ getPostView() โดยเรียกรายการ Post ที่กดเปิดดู
สร้างไฟล์ helper.dart
สร้างไฟล์ helper.dart เพื่อเรียกใช้งานในตัวอย่างนี้จะเรียกใช้งานการแปลง timestamp เป็น ตัวหนังสือ เช่น 2 วันที่แล้ว เป็นต้น ดูตัวอย่างโค้ด
import 'package:intl/intl.dart';
class Helper {
Helper();
String readTimestamp(int timestamp) {
var now = new DateTime.now();
var format = new DateFormat('HH:mm a');
var date = new DateTime.fromMillisecondsSinceEpoch(timestamp * 1000);
var diff = now.difference(date);
var time = '';
if (diff.inSeconds <= 0 ||
diff.inSeconds > 0 && diff.inMinutes == 0 ||
diff.inMinutes > 0 && diff.inHours == 0 ||
diff.inHours > 0 && diff.inDays == 0) {
time = format.format(date);
} else if (diff.inDays > 0 && diff.inDays < 7) {
if (diff.inDays == 1) {
time = diff.inDays.toString() + ' วันที่แล้ว';
} else {
time = diff.inDays.toString() + ' วันที่แล้ว';
}
} else {
if (diff.inDays == 7) {
time = (diff.inDays / 7).floor().toString() + ' สัปดาห์ที่แล้ว';
} else {
time = (diff.inDays / 7).floor().toString() + ' สัปดาห์ที่แล้ว';
}
}
return time;
}
}
สร้างไฟล์ main_page.dart
เป็นไฟล์หลักที่โหลดรายการ post มาแสดงผลใน list tile
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:yourpackage/api_provider.dart';
import 'post_view_page.dart';
import 'package:yourpackage/helper.dart';
class MainPage extends StatefulWidget {
@override
_MainPageState createState() => _MainPageState();
}
class _MainPageState extends State<MainPage> {
List items = [];
bool isLoading = true;
ApiProvider apiProvider = ApiProvider();
Helper helper = Helper();
Future fetchPost() async {
try {
var response = await apiProvider.getPost();
if (response.statusCode == 200) {
var jsonResponse = json.decode(response.body);
setState(() {
isLoading = false;
items = jsonResponse['data'];
//print(items);
});
}
} catch (error) {
setState(() {
isLoading = false;
});
print(error);
}
}
@override
void initState() {
fetchPost();
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Your App Name'),
),
body: isLoading
? Center(
child: CircularProgressIndicator(),
)
: ListView.builder(
itemBuilder: (BuildContext context, int index) {
var item = items[index];
return Padding(
padding: const EdgeInsets.only(
left: 0.0, right: 0.0, bottom: 4.0),
child: Container(
color: Colors.white,
child: ListTile(
onTap: () {
Navigator.of(context).push(MaterialPageRoute(
builder: (context) => PostViewPage(item['id'])));
},
title: Text('${item['name']}'),
subtitle: Row(
children: <Widget>[
Icon(
Icons.description,
size: 14.0,
),
Text(' ${item['category_name']} '),
Icon(
Icons.calendar_today,
size: 14.0,
),
Text(
' ${helper.readTimestamp(item['created_at'])} '),
Icon(
Icons.person,
size: 14.0,
),
Text(' ${item['created_by_fullname']} '),
],
),
leading: Image.network(
'${item['image']}',
),
trailing: Icon(Icons.keyboard_arrow_right),
),
),
);
},
itemCount: items != null ? items.length : 0,
));
}
}
ทดลอง run
สร้างไฟล์ post_view_page.dart
สร้างไฟล์ /lib/post_view_page.dart เพื่อแสดงผลรายละเอียด post
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:yourpackage/api_provider.dart';
import 'package:yourpackage/helper.dart';
import 'package:html2md/html2md.dart' as html2md;
import 'package:flutter_markdown/flutter_markdown.dart';
class PostViewPage extends StatefulWidget {
int id;
PostViewPage(this.id);
@override
_PostViewPageState createState() => _PostViewPageState();
}
class _PostViewPageState extends State<PostViewPage> {
bool isLoading = true;
Helper helper = Helper();
ApiProvider apiProvider = ApiProvider();
String post_category;
String post_name;
String post_body;
int post_created_at;
String post_created_by_fullname;
Future fetchPostView() async {
try {
var response = await apiProvider.getPostView(widget.id);
if (response.statusCode == 200) {
var jsonResponse = json.decode(response.body);
setState(() {
isLoading = false;
post_category = jsonResponse['data']['category_name'];
post_name = jsonResponse['data']['name'];
post_body = html2md.convert(jsonResponse['data']['body']);
post_created_at = jsonResponse['data']['created_at'].toInt();
post_created_by_fullname =
jsonResponse['data']['created_by_fullname'].toString();
});
}
} catch (error) {
setState(() {
isLoading = false;
});
print(error);
}
}
@override
void initState() {
super.initState();
fetchPostView();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('${post_name}'),
),
body: isLoading
? Center(
child: CircularProgressIndicator(),
)
: ListView(
children: <Widget>[
Column(
children: <Widget>[
Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
color: Colors.white,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Center(
child: Text(
post_name,
style: Theme.of(context).textTheme.title,
)),
Row(
children: <Widget>[
Icon(
Icons.description,
size: 14.0,
),
Text(' ${post_category} '),
Icon(
Icons.calendar_today,
size: 14.0,
),
Text(
' ${helper.readTimestamp(post_created_at)} '),
Icon(
Icons.person,
size: 14.0,
),
Text(' ${post_created_by_fullname} '),
],
),
MarkdownBody(
data: post_body,
),
],
),
)),
),
],
),
],
));
}
}
ทดลองกดจากรายการ
ความคิดเห็น