Skip to main content

请求远程数据

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 APIFormData拦截器请求取消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
}
}