赞
踩
- class MyHomePage extends StatefulWidget {
- const MyHomePage({super.key, required this.title});
-
- final String title;
-
- @override
- State<MyHomePage> createState() => _MyHomePageState();
- }
-
- class _MyHomePageState extends State<MyHomePage> {
- @override
- Widget build(BuildContext context) {
- return Scaffold(
- body: Column(
- mainAxisAlignment: MainAxisAlignment.spaceAround,
- crossAxisAlignment: CrossAxisAlignment.center,
- children: [
- const SizedBox(
- height: 0,
- width: double.infinity,
- ),
- TextButton(
- child: const Text("show dialog"),
- onPressed: () => showCustomDialog(),
- ),
- TextButton(
- child: const Text("show delay dialog"),
- onPressed: () => showDelayDialog(),
- ),
- TextButton(
- child: const Text("show sheet"),
- onPressed: () => showSheetDialog(),
- ),
- ],
- ),
- );
- }
-
- void showCustomDialog() {
- CustomDialog.show(context, (context, dismiss) {
- return Container(
- width: 200,
- height: 100,
- color: Colors.white,
- child: Center(
- child:
- TextButton(onPressed: () => dismiss(), child: const Text("POP")),
- ),
- );
- });
- }
-
- void showSheetDialog() {
- CustomDialog.showBottomSheet(context, (ctx, dismiss) {
- return Container(
- height: 300,
- color: Colors.white,
- margin: const EdgeInsets.all(20),
- child: Center(
- child:
- TextButton(onPressed: () => dismiss(), child: const Text("POP")),
- ),
- );
- });
- }
-
- void showDelayDialog() {
- CustomDialog.show(context, (context, dismiss) {
- //延时关闭
- Timer(const Duration(seconds: 2), () => dismiss());
-
- return Container(
- width: 200,
- height: 100,
- color: Colors.yellow,
- child: const Center(
- child: Text("等待"),
- ),
- );
- }, cancellable: true);
- }
- }
-
- class CustomDialog {
- static void show(BuildContext context,
- Widget Function(BuildContext ctx, void Function() dismiss) builder,
- {bool cancellable = false}) {
- showDialog(
- context: context,
- barrierDismissible: cancellable,
- builder: (ctx) {
- return WillPopScope(
- child: Dialog(
- child: builder(ctx, () => Navigator.of(ctx).pop()),
- backgroundColor: Colors.transparent,
- shape: const RoundedRectangleBorder(
- borderRadius: BorderRadius.all(Radius.circular(0.0))),
- elevation: 0,
- alignment: Alignment.center,
- ),
- onWillPop: () async => cancellable,
- );
- },
- );
- }
-
- static void showBottomSheet(BuildContext context,
- Widget Function(BuildContext ctx, void Function() dismiss) builder,
- {bool cancellable = true}) {
- showModalBottomSheet(
- context: context,
- isDismissible: cancellable,
- enableDrag: cancellable,
- isScrollControlled: true,
- builder: (BuildContext ctx) {
- return WillPopScope(
- child: builder(ctx, () => Navigator.of(ctx).pop()),
- onWillPop: () async => cancellable,
- );
- },
- //不设置会默认使用屏幕最大宽度而不是子组件宽度
- constraints: const BoxConstraints(
- minWidth: 0,
- minHeight: 0,
- maxWidth: double.infinity,
- maxHeight: double.infinity),
- backgroundColor: Colors.transparent,
- );
- }
- }
- title:标题
- titlePadding:标题内边距
- titleTextStyle:标题样式
- content:内容,推荐用SingleChildScrollView包裹
- contentPadding:EdgeInsets.fromLTRB(24.0, 20.0, 24.0, 24.0),内容内边距
- contentTextStyle:内容样式
- actions:按钮集合,可以放多个
- actionsPadding:EdgeInsets.zero,actions内边距
- buttonPadding:按钮内边距
- backgroundColor:背景色
- elevation:阴影
- shape:形状
- scrollable = false:
- title:标题
- titlePadding:EdgeInsets.fromLTRB(24.0, 24.0, 24.0, 0.0),标题内边距
- titleTextStyle:标题样式
- children:子节点
- contentPadding:EdgeInsets.fromLTRB(0.0, 12.0, 0.0, 16.0),内容内边距
- backgroundColor:背景色
- elevation:阴影
- shape:形状
dio: any # dio依赖包
- class MyHomePage extends StatefulWidget {
- const MyHomePage({super.key, required this.title});
-
- final String title;
-
- @override
- State<MyHomePage> createState() => _MyHomePageState();
- }
-
- class _MyHomePageState extends State<MyHomePage> {
-
-
- void _showLoadingDialog() {
- showDialog(
- context: context,
- builder: (context) {
- // 用Scaffold返回显示的内容,能跟随主题
- return Scaffold(
- backgroundColor: Colors.transparent, // 设置透明背影
- body: Center( // 居中显示
- child: Column( // 定义垂直布局
- mainAxisAlignment: MainAxisAlignment.center, // 主轴居中布局,相关介绍可以搜下flutter-ui的内容
- children: <Widget>[
- // CircularProgressIndicator自带loading效果,需要宽高设置可在外加一层sizedbox,设置宽高即可
- CircularProgressIndicator(),
- SizedBox(
- height: 10,
- ),
- Text('loading'), // 文字
- // 触发关闭窗口
- GestureDetector(
- child: Text('close dialog'),
- onTap: () {
- print('close');
- },
- ),
- ],
- ), // 自带loading效果,需要宽高设置可在外加一层sizedbox,设置宽高即可
- ),
- );
- },
- );
- }
-
-
- @override
- Widget build(BuildContext context) {
- return Scaffold(
- appBar: AppBar(
- backgroundColor: Theme.of(context).colorScheme.inversePrimary,
- title: Text(widget.title),
- ),
- body: Center(
- child: GestureDetector(
- onTap: () {
- _showLoadingDialog();
- },
- child: const Text(
- '\n点击显示弹窗一\n',
- ),
- ),
- ),
- );
- }
- }
- import 'package:dio/dio.dart' show Dio, InterceptorsWrapper;
- import 'package:flutter_custom_widget/http/Loading.dart';
-
- Dio? dio;
-
- class Http {
- static Dio? instance() {
- if (dio != null) {
- return dio;// 实例化dio
- }
- dio = Dio();
- // 增加拦截器
- dio?.interceptors.add(
- InterceptorsWrapper(
- // 接口请求前数据处理
- onRequest: (options,handler) {
- Loading.before("onRequest");
- },
- // 接口成功返回时处理
- onResponse: (resp,handler) {
- Loading.complete();
- },
- // 接口报错时处理
- onError: ( error,handler) {
- Loading.complete();
- },
- ),
- );
- return dio;
- }
-
- /// get接口请求
- /// path: 接口地址
- static get(path) {
- return instance()?.get(path);
- }
- }
-
-
- import 'package:flutter/material.dart';
-
- class Loading {
- static dynamic ctx;
-
- static void before(text) {
- // 请求前显示弹窗
- showDialog(
- context: ctx,
- builder: (context) {
- return Index(text: text);
- },
- );
- }
-
- static void complete() {
- // 完成后关闭loading窗口
- Navigator.of(ctx, rootNavigator: true).pop();
- }
- }
-
- // 弹窗内容
- class Index extends StatelessWidget {
- final String? text;
-
- Index({Key? key, @required this.text}):super(key: key);
-
- @override
- Widget build(BuildContext context) {
- return Text('$text');
- }
- }
- @override
- Widget build(BuildContext context) {
- ......
-
- Loading.ctx = context; // 注入context
-
- ......
-
- }
- class Loading {
- static dynamic ctx;
- static void before(text) {
- // 请求前显示弹窗
- // showDialog(context: ctx, builder: (context) {
- // return Index(text:text);
- // );
- }
-
- static void complete() {
- // 完成后关闭loading窗口
- // Navigator.of(ctx, rootNavigator: true).pop();
- }
- }
- class MyHomePage extends StatefulWidget {
- const MyHomePage({super.key, required this.title});
-
- final String title;
-
- @override
- State<MyHomePage> createState() => _MyHomePageState();
- }
-
- class _MyHomePageState extends State<MyHomePage> {
-
- @override
- Widget build(BuildContext context) {
- Loading.ctx = context; // 注入context
- return Scaffold(
- appBar: AppBar(
- backgroundColor: Theme.of(context).colorScheme.inversePrimary,
- title: Text(widget.title),
- ),
- body: Center(
- child: GestureDetector(
- onTap: () {
- Http.get('https://blog.csdn.net/u013491829/article/details/137032263');
- },
- child: const Text(
- '\n点击进行网络加载\n',
- ),
- ),
- ),
- );
- }
- }
并发请求,loading只需要保证有一个在当前运行。接口返回结束,只需要保证最后一个完成时,关闭loading。
- 使用Set有排重作用,比较使用用来管理并发请求地址。通过Set.length控制弹窗与关闭窗口。
- 增加LoadingStatus判断是否已经有弹窗存在
- 修改onRequest/onResponse/onError入参
- import 'package:flutter/material.dart';
-
- Set dict = Set();
- bool loadingStatus = false;
- class Loading {
- static dynamic ctx;
-
- static void before(uri, text) {
- dict.add(uri); // 放入set变量中
- // 已有弹窗,则不再显示弹窗, dict.length >= 2 保证了有一个执行弹窗即可,
- if (loadingStatus == true || dict.length >= 2) {
- return ;
- }
- loadingStatus = true; // 修改状态
- // 请求前显示弹窗
- showDialog(
- context: ctx,
- builder: (context) {
- return Index(text: text);
- },
- );
- }
-
- static void complete(uri) {
- dict.remove(uri);
- // 所有接口接口返回并有弹窗
- if (dict.length == 0 && loadingStatus == true) {
- loadingStatus = false; // 修改状态
- // 完成后关闭loading窗口
- Navigator.of(ctx, rootNavigator: true).pop();
- }
- }
- }
-
案例 切换到分支flutter_custom_widget
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。