您当前的位置: 首页 > 慢生活 > 程序人生 网站首页程序人生
flutter-示例目录(网络请求及windows端运行与网络请求的调试(类似web的f12的network))
发布时间:2026-07-09 15:53:01编辑:雪饮阅读()
-
按之前的来说示例目录应该是在
https://flutter.github.io/samples/Flutter
但这个已经明显无法打开了。
按现在的来看,我觉得应该就是
https://docs.flutter.dev/reference/learning-resources
这个页面
这样就和上篇重复了。
那么我还有一种理解就是在这个页面中筛选项目勾选Sample code
这个页面其实感觉没有什么可看的,我更想要动手实践下,接下来我就以常见的搜索功能为例。
那么首先我们的搜索页面布局我们单独一个dart文件,我想实现的是上半部分是搜索头部,包含api接口地址,authorization(如果自己的接口,一般可以不用鉴权,这里我是借用别人的接口),搜索关键词,屏蔽关键词管理,搜索结果展示及分页。
这个目标比较多,这里仅仅只是初步实现一个表面的,就到发送搜索请求并在请求结束将响应内容打印到控制台为目的。
那么建立search_result_table.dart文件内容如:
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
class SearchResultTable extends StatefulWidget {
const SearchResultTable({super.key});
@override
State<SearchResultTable> createState() => _SearchResultTableState();
}
class _SearchResultTableState extends State<SearchResultTable> {
final TextEditingController _apiController = TextEditingController(
text: "https://search-server.xoczl.net/Search/Social/Query",
);
final TextEditingController _keywordController = TextEditingController(
text: "搭讪",
);
final TextEditingController authorizationController = TextEditingController(
text:
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoi5ri45a6iLTEiLCJpZCI6IjI0MDAwMDAwMDAyIiwiaXAiOiIzNS4xNjMuMjQ2LjQ1IiwidHlwZSI6MywicGFja2FnZV9pZCI6MSwibGV2ZWwiOjEsImlzcyI6IkdVRVNUIiwic3ViIjoic29jaWFsLXNlcnZlciIsImV4cCI6MTc4NDE3ODE5NCwibmJmIjoxNzgzNTczMzk0LCJpYXQiOjE3ODM1NzMzOTQsImp0aSI6ImUwMTdmOWI2MjlmNDRjMmU5YTMxMDlkOWZkNWYzMDEyIn0.Dq6nXZqmxqD4YDpMAjDe3AMrKUyn3v7T8sEMoHLwmTM",
);
@override
void dispose() {
_apiController.dispose();
_keywordController.dispose();
authorizationController.dispose();
super.dispose();
}
Widget _buildGridCell({
required Widget child,
bool rightBorder = false,
bool bottomBorder = false,
}) {
return Container(
decoration: BoxDecoration(
border: Border(
right: rightBorder ? const BorderSide() : BorderSide.none,
bottom: bottomBorder ? const BorderSide() : BorderSide.none,
),
),
child: child,
);
}
Widget _buildHeaderCell(String text) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: Text(text, style: const TextStyle(fontWeight: FontWeight.bold)),
);
}
@override
Widget build(BuildContext context) {
return Container(
decoration: BoxDecoration(border: Border.all()),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
children: [
Expanded(
child: TextField(
controller: _apiController,
decoration: const InputDecoration(
hintText: '请输入api地址',
border: OutlineInputBorder(),
),
),
),
const SizedBox(width: 8),
Expanded(
child: TextField(
controller: _keywordController,
decoration: const InputDecoration(
hintText: '请输入关键词',
border: OutlineInputBorder(),
),
),
),
const SizedBox(width: 8),
Expanded(
child: TextField(
controller: authorizationController,
decoration: const InputDecoration(
hintText: '请输入authorization',
border: OutlineInputBorder(),
),
),
),
],
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
children: [
//搜索
ElevatedButton(
onPressed: () async {
if (_apiController.text.isEmpty) {
ScaffoldMessenger.of(
context,
).showSnackBar(const SnackBar(content: Text('请输入api地址')));
return;
}
if (_keywordController.text.isEmpty) {
ScaffoldMessenger.of(
context,
).showSnackBar(const SnackBar(content: Text('请输入关键词')));
return;
}
/*
发起http的post请求
请求头需要包含authorization
请求头content-type的值为application/json
请求的json对象格式为:
var jsonObject=[{"name":"social.post","limit":100,"page":1,"or":[{"field":"title","op":"$like","value":"%kasumi"},{"field":"tags","op":"$in","value":["kasumi"]}],"and":[{"field":"categories_id","op":"$nin","value":["137","257","347","264","764","931","97","101","365","534","115","361","335","389","336","425","367","456","930","85","2","382","78","252","154","1108","917","416","344","1107","337","74","99","281","93","230","454","166","175","397","452","414","285","928","766","1009","288","113","322","49","1106","426","81","758","332","104","88","364","1011","333","57","240","695","86","396","677","41","265","959","102","56","358","221","301","929","242","187","224","789","340","349","55","231","402","105","169","461","346","50","182","210","676","48","292","95","413","131","334","35","348","310","455","43","246","77","401","330","293","355","84","161","23","312","1012","359","771","87","124","163","395","1214","123","927","926","388","39","934","202","274","453","214","286","932","375","405","212","404","38","7","46","40","363","268","1110","75","350","262","218","394","92","37","247","128","675","933"]},{"field":"status","op":"$in","value":[1,9]}],"sort":[{"field":"create_time","order":"DESC"}]}];
这个json对象中仅仅用输入的关键词替换这个对象中的kasumi
*/
final keyword = _keywordController.text;
final apiUrl = _apiController.text;
final auth = authorizationController.text;
final requestBody = [
{
"name": "social.post",
"limit": 100,
"page": 1,
"or": [
{
"field": "title",
"op": "\$like",
"value": "%$keyword",
},
{
"field": "tags",
"op": "\$in",
"value": [keyword],
},
],
"and": [
{
"field": "categories_id",
"op": "\$nin",
"value": [
"137",
"257",
"347",
"264",
"764",
"931",
"97",
"101",
"365",
"534",
"115",
"361",
"335",
"389",
"336",
"425",
"367",
"456",
"930",
"85",
"2",
"382",
"78",
"252",
"154",
"1108",
"917",
"416",
"344",
"1107",
"337",
"74",
"99",
"281",
"93",
"230",
"454",
"166",
"175",
"397",
"452",
"414",
"285",
"928",
"766",
"1009",
"288",
"113",
"322",
"49",
"1106",
"426",
"81",
"758",
"332",
"104",
"88",
"364",
"1011",
"333",
"57",
"240",
"695",
"86",
"396",
"677",
"41",
"265",
"959",
"102",
"56",
"358",
"221",
"301",
"929",
"242",
"187",
"224",
"789",
"340",
"349",
"55",
"231",
"402",
"105",
"169",
"461",
"346",
"50",
"182",
"210",
"676",
"48",
"292",
"95",
"413",
"131",
"334",
"35",
"348",
"310",
"455",
"43",
"246",
"77",
"401",
"330",
"293",
"355",
"84",
"161",
"23",
"312",
"1012",
"359",
"771",
"87",
"124",
"163",
"395",
"1214",
"123",
"927",
"926",
"388",
"39",
"934",
"202",
"274",
"453",
"214",
"286",
"932",
"375",
"405",
"212",
"404",
"38",
"7",
"46",
"40",
"363",
"268",
"1110",
"75",
"350",
"262",
"218",
"394",
"92",
"37",
"247",
"128",
"675",
"933",
],
},
{
"field": "status",
"op": "\$in",
"value": [1, 9],
},
],
"sort": [
{"field": "create_time", "order": "DESC"},
],
},
];
try {
final response = await http.post(
Uri.parse(apiUrl),
headers: {
'authorization': auth,
'Content-Type': 'application/json',
'origin': 'https://xn--10jong-2o7io6t.30gnao.space',
},
body: jsonEncode(requestBody),
);
if (response.statusCode == 200) {
debugPrint('请求成功, 响应: ${response.body}');
} else {
debugPrint(
'请求失败, 状态码: ${response.statusCode}, 响应: ${response.body}',
);
}
} catch (e) {
debugPrint('请求异常: $e');
}
debugPrint(
'搜索按钮被点击, api: ${_apiController.text}, 关键词: ${_keywordController.text}',
);
},
child: const Text('搜索'),
),
const SizedBox(width: 8),
ElevatedButton(
onPressed: () {
debugPrint('屏蔽关键词管理按钮被点击');
},
child: const Text('屏蔽关键词管理'),
),
],
),
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 8.0),
child: Row(
children: [
const Text(
'搜索结果',
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 16),
),
],
),
),
const Divider(),
Row(
children: [
Expanded(
flex: 2,
child: _buildGridCell(
child: _buildHeaderCell('标题'),
rightBorder: true,
bottomBorder: true,
),
),
Expanded(
flex: 2,
child: _buildGridCell(
child: _buildHeaderCell('图片'),
rightBorder: true,
bottomBorder: true,
),
),
Expanded(
child: _buildGridCell(
child: _buildHeaderCell('操作'),
bottomBorder: true,
),
),
],
),
Row(
children: [
Expanded(
flex: 2,
child: _buildGridCell(
child: const Padding(
padding: EdgeInsets.all(8.0),
child: Text('标题1'),
),
rightBorder: true,
bottomBorder: true,
),
),
Expanded(
flex: 2,
child: _buildGridCell(
child: const Padding(
padding: EdgeInsets.all(8.0),
child: Text('图片1.jpg'),
),
rightBorder: true,
bottomBorder: true,
),
),
Expanded(
child: _buildGridCell(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: ElevatedButton(
style: ElevatedButton.styleFrom(
minimumSize: Size.zero,
padding: const EdgeInsets.symmetric(
horizontal: 12,
vertical: 8,
),
tapTargetSize: MaterialTapTargetSize.shrinkWrap,
),
onPressed: () {
debugPrint('详情按钮被点击');
},
child: const Text('详情'),
),
),
bottomBorder: true,
),
),
],
),
Row(
children: [
Expanded(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Text('共10条记录,共2页'),
const SizedBox(width: 16),
ElevatedButton(
style: ElevatedButton.styleFrom(
minimumSize: Size.zero,
padding: const EdgeInsets.symmetric(
horizontal: 12,
vertical: 8,
),
tapTargetSize: MaterialTapTargetSize.shrinkWrap,
),
onPressed: () {
debugPrint('下一页按钮被点击');
},
child: const Text('下一页'),
),
const SizedBox(width: 8),
ElevatedButton(
style: ElevatedButton.styleFrom(
minimumSize: Size.zero,
padding: const EdgeInsets.symmetric(
horizontal: 12,
vertical: 8,
),
tapTargetSize: MaterialTapTargetSize.shrinkWrap,
),
onPressed: () {
debugPrint('上一页按钮被点击');
},
child: const Text('上一页'),
),
],
),
),
),
],
),
],
),
);
}
}
然后之前的main.dart中引入
import 'search_result_table.dart';
以及挂载
children: [
const Text('搜索结果页面'),
const Divider(),
const SearchResultTable(),
Text(
'$_counter',
style: Theme.of(context).textTheme.headlineMedium,
),
],
由于目标接口可能会导致跨域,这个时候web环境调试就会有问题,所以这里我想要实现windows的桌面版的调试,所以先关闭之前的web调试实例,如果开了多个,都关闭吧(除非你有特殊要求,不然尽量节约点资源吧)。
然后在trae左侧的debug的虫子图标上面点击进入”运行和调试”里面选择到如:
flutter_application_1 (Flutter Windows)
这种带有Flutter windows的调试选项。
那么可能会报错于trae控制台:
Error: Unable to find suitable Visual Studio toolchain. Please run `flutter doctor` for more details.
按提示,运行flutter doctor结果是:
PS D:\flutterDemo\flutterDemo1\flutter_application_1> flutter doctor
Flutter assets will be downloaded from https://storage.flutter-io.cn. Make sure you trust this source!
Doctor summary (to see all details, run flutter doctor -v):
[√] Flutter (Channel stable, 3.44.4, on Microsoft Windows [版本 10.0.26200.8737], locale zh-CN)
[√] Windows Version (11 专业版 64-bit, 25H2, 2009)
[X] Android toolchain - develop for Android devices
X Unable to locate Android SDK.
Install Android Studio from: https://developer.android.com/studio/index.html
On first launch it will assist you in installing the Android SDK components.
(or visit https://flutter.dev/to/windows-android-setup for detailed instructions).
If the Android SDK has been installed to a custom location, please use
`flutter config --android-sdk` to update to that location.
[X] Chrome - develop for the web (Cannot find Chrome executable at .\Google\Chrome\Application\chrome.exe)
! Cannot find Chrome. Try setting CHROME_EXECUTABLE to a Chrome executable.
[X] Visual Studio - develop Windows apps
X Visual Studio not installed; this is necessary to develop Windows apps.
Download at https://visualstudio.microsoft.com/downloads/.
Please install the "Desktop development with C++" workload, including all of its default components
[√] Connected device (2 available)
[!] Network resources
X An HTTP error occurred while checking "https://github.com/": 信号灯超时时间已到
! Doctor found issues in 4 categories.
根据我们这里的情况,也就是要去
https://visualstudio.microsoft.com/downloads/
这里下载visual studio
并在安装的时候默认组件的要勾选"Desktop development with C++"
进入下载界面后我是选择community社区版本
下载的VisualStudioSetup.exe其实并不大,直接5M多,这种就是在线安装了。
既然是中文语言的,那就对应"Desktop development with C++"的就是使用”c++的桌面开发”

安装完成后重新启动trae,然后重新启动调试选项为windows
然后就能看到windows版本的界面就出现了。
我们刚才写的这个界面中其实是有发送网络请求的,那么在windows运行情况下,如何查看network的网络请求信息呢?
在trae左侧有个flutter的图标(这个图标应该是安装了flutter扩展才会出现的),然后点击后在里面可以切换到network,然后在windows中我们刚才写的搜索按钮上点击,后再回到trae中flutter图标里面的network里面就能看到了。和web端的基本是一致的。
关键字词:flutter,network,f12,windows,网络请求,示例目录
上一篇:flutter-Cookbook
下一篇:返回列表