请求远程数据
Flutter JSON字符串和Map类型的转换
Map转换成Json
import 'dart:convert'
Map userInfo={
"username":"张三",
"age":20
};
print(json.encode(userInfo));
Json转换成Map
String str='{"username":"张三","age":20}';
print(json.decode(str));
Map info=json.decode(str);
print(info["username"]);
Dio请求数据
dio
是一个强大的 Dart Http
请求库,支持 Restful API
、FormData
、拦截器
、请求取消
、Cookie管理
、文件上传/下载
、超时
、自定义适配器等
...
官网:https://pub.dev/packages/dio
中文文档:https://github.com/flutterchina/dio/blob/master/README-ZH.md
Dio 的配置
dependencies:
dio: ^4.0.6
import 'package:dio/dio.dart';
var response = await Dio().get('https://reqres.in/api/users?page=2');
print(response.data);
print(response.data is Map);
Dio Get
_getData() async {
var response = await Dio().get('https://reqres.in/api/users?page=2',
queryParameters:{
"username": "zhangsan"
}
);
print(response.data is Map);
print(response.data["msg"]);
}
Dio Post
_postData() async{
var response = await Dio().post('https://reqres.in/api/users?page=2',
data: {
"username":"张三111",
"age":"20"
}
);
print(response.data);
print(response.data is Map);
}
Dio Put
_putData() async {
var response = await Dio().put('https://reqres.in/api/users?page=2',
data: {
"username": "张三111",
"age": "20"
}
);
print(response.data);
print(response.data is Map);
}
Dio Delete
_deleteData() async {
var response = await Dio().delete('https://reqres.in/api/users?page=2',
queryParameters: {
"id": "1"
}
);
print(response.data);
print(response.data is Map);
}
Dio 请求数据渲染数据示例,通过数组长度判断数据渲染数据
import 'package:flutter/material.dart';
import 'package:dio/dio.dart';
class CategoryPage extends StatefulWidget {
const CategoryPage({super.key});
@override
State<CategoryPage> createState() => _CategoryPageState();
}
class _CategoryPageState extends State<CategoryPage> {
List _list = [];
@override
void initState() {
super.initState();
_getCateList();
}
_getCateList() async {
var response = await Dio().get("https://reqres.in/api/users?page=2");
// return result.data;
print(response.data);
setState(() {
_list = response.data["result"];
});
}
@override
Widget build(BuildContext context) {
return _list.isNotEmpty
? ListView(
children: _list.map((value) {
return Column(
children: [
ListTile(
title: Text(value["title"]),
),
const Divider()
],
);
}).toList(),
)
: const Center(
child: CircularProgressIndicator(),
);
}
}
Dio 请求数据渲染数据示例,FutureBuilder 渲染数据
import 'package:flutter/material.dart';
import 'package:dio/dio.dart';
class MessagePage extends StatefulWidget {
const MessagePage({super.key});
@override
State<MessagePage> createState() => _MessagePageState();
}
class _MessagePageState extends State<MessagePage> {
_getCateList() async {
var response = await Dio().get("https://reqres.in/api/users");
return response.data["result"];
}
@override
Widget build(BuildContext context) {
return FutureBuilder(
future: _getCateList(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
if (snapshot.hasError) {
return Center(
child: Text("Error:${snapshot.error}")
);
}else {
var response = snapshot.data as List;
return ListView(
children: response.map((value) {
return ListTile(
title: Text("${value["title"]}"),
);
}).toList(),
);
}
} else {
return const Center(
child: CircularProgressIndicator()
);
}
}
); // FutureBuilder
}
}
下拉刷新 上拉分页加载更多
下拉刷新和上拉分页
在Flutter官方 sdk
中给我们提供了下拉刷新的组件 RefreshIndicator
。但是没有提供上拉分页加载更多
的组件。但是在Flutter ListView
中有一个 ScrollController
属性,它就是专门来控制 ListView
滑动事件,
在这里我们可以根据 ListView
的位置来判断是否滑动到了底部来做加载更多的处理。
API测试接口 https://www.phonegap100.com/appapi.php?a=getPortalList&catid=20&page=1
RefreshIndicator 组件实现下拉刷新
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:dio/dio.dart';
class NewsPage extends StatefulWidget {
const NewsPage({super.key});
@override
State<NewsPage> createState() => _NewsPageState();
}
class _NewsPageState extends State<NewsPage> {
List _list = [];
@override
void initState() {
super.initState();
_getData();
}
_getData() async {
String apiUri = "https://www.phonegap100.com/appapi.php?a=getPortalList&catid=20&page=1";
var response = await Dio().get(apiUri);
var result = json.decode(response.data);
setState(() {
_list = result["result"];
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Title'),
),
body: _list.isNotEmpty
? RefreshIndicator(
child: ListView(
children: _list.map((value) {
return ListTile(
title: Text("${value["title"]}"),
);
}).toList(),
),
onRefresh: () async{
print("执行");
await _getData();
}
) : const Center(
child: CircularProgressIndicator()
),
);
}
}
上拉分页加载更多
上拉分页加载更多主要通过 ListTile
监听 ScrollController
实现
_scrollController.position.pixels
滚动的距离
_scrollController.position.maxScrollExtent
总距离
核心代码
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:dio/dio.dart';
class NewsPage extends StatefulWidget {
const NewsPage({super.key});
@override
State<NewsPage> createState() => _NewsPageState();
}
class _NewsPageState extends State<NewsPage> {
ScrollController _scrollController = ScrollController(); //listview的控制器
List _list = [];
int _page=1;
@override
void initState() {
super.initState();
_getData();
//监听滚动条
_scrollController.addListener(() {
if (_scrollController.position.pixels > _scrollController.position.maxScrollExtent-20) {
_getData();
}
});
}
_getData() async {
String apiUri = "https://www.phonegap100.com/appapi.php?a=getPortalList&catid=20&page=$_page";
var response = await Dio().get(apiUri);
var result = json.decode(response.data);
setState(() {
_list.addAll(result["result"]);
_page++;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Title'),
), // AppBar
body: _list.isNotEmpty ? RefreshIndicator(
child: ListView(
controller: _scrollController,
children: _list.map((value) {
return ListTile(
title: Text("${value["title"]}"),
);
}).toList(),
), // ListView
onRefresh: () async{
print("执行");
await _getData();
}
) : const Center(
child: CircularProgressIndicator()
), // Center
); // Scaffold
}
}