昆明網(wǎng)站建設(shè)-中國(guó)互聯(lián)精準(zhǔn)客戶(hù)數(shù)據(jù)采集軟件
背景:
在使用GetX框架時(shí),同時(shí)使用了Get.snackbar提示框和Get.dialog加載框,當(dāng)這兩個(gè)widget同時(shí)存在時(shí),Get.dialog加載框調(diào)用Get.back()無(wú)法正常關(guān)閉。
沖突解釋:
之所以會(huì)產(chǎn)生沖突,是因?yàn)镚et.snackbar在關(guān)閉時(shí)會(huì)有一個(gè)動(dòng)畫(huà),這個(gè)動(dòng)畫(huà)的默認(rèn)持續(xù)時(shí)間為1s,這個(gè)動(dòng)畫(huà)的持續(xù)時(shí)間內(nèi),Get.snackbar并沒(méi)有真正意義上的關(guān)閉,這時(shí)候我們調(diào)用Get.back()是無(wú)法關(guān)閉Get.dialog。
實(shí)現(xiàn):
- 創(chuàng)建一個(gè)統(tǒng)一的SnackBarManager去管理提示框。
import 'package:get/get.dart';
import 'package:flutter/material.dart';class SnackBarManager {factory SnackBarManager() => instance;static final SnackBarManager instance = SnackBarManager._internal();SnackBarManager._internal();String _lastMessage = '';int _lastDuration = 0;int _lastTime = 0;void showSnackBar(String title, String message, {Color? backgroundColor, Duration? duration}) {var currentTime = DateTime.now().millisecondsSinceEpoch;// 相同消息持續(xù)時(shí)間內(nèi)重復(fù)提交時(shí),返回if (currentTime - _lastTime < _lastDuration * 1000 && _lastMessage == message) {return;}dismissSnackBar();Get.snackbar(title,message,backgroundColor: backgroundColor ?? Colors.black12,duration: duration ?? Duration(seconds: 2), // 提示框持續(xù)時(shí)間animationDuration: Duration(milliseconds: 0), // 過(guò)渡動(dòng)畫(huà)的時(shí)間,這里設(shè)置為0是為了在使用Get.dialog時(shí)避免關(guān)閉沖突);_lastDuration = duration?.inSeconds ?? 2;_lastTime = DateTime.now().millisecondsSinceEpoch;_lastMessage = message;}void dismissSnackBar() {Get.closeCurrentSnackbar();}
}
這是一個(gè)避免重復(fù)顯示的顯示的提示框,可參考博客:Flutter中Get.snackbar避免重復(fù)顯示的實(shí)現(xiàn)
2. 創(chuàng)建一個(gè)LoadingDialog去實(shí)現(xiàn)加載框。
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:get/get_core/src/get_main.dart';class LoadingDialog {static void show([String? msg]) {Get.dialog(PopScope(canPop: false,child: Center(child: Container(padding: EdgeInsets.symmetric(horizontal: 24, vertical: 16), // 減小內(nèi)邊距decoration: BoxDecoration(color: Colors.white,borderRadius: BorderRadius.circular(8),),child: Row(mainAxisSize: MainAxisSize.min, // 設(shè)置為最小寬度children: [SizedBox(width: 24, // 減小加載圖標(biāo)尺寸height: 24,child: CircularProgressIndicator(strokeWidth: 2.0, // 可以適當(dāng)減小進(jìn)度條寬度),),SizedBox(width: 12), // 減小間距Text(msg ?? "加載中...",style: TextStyle(fontSize: 14, color: Colors.black), // 可以適當(dāng)調(diào)整字體大小),],),),),),barrierDismissible: false,);}static void hide() {if (Get.isDialogOpen ?? false) {// 先關(guān)閉 SnackbarGet.closeCurrentSnackbar();// 添加延遲以確保 Snackbar 已關(guān)閉Future.delayed(Duration(milliseconds: 100), () {if (Get.isDialogOpen ?? false) {Get.back();}});}}
}
在關(guān)閉加載框之前,會(huì)先關(guān)閉提示框,由于Get.snackbar動(dòng)畫(huà)時(shí)長(zhǎng)已經(jīng)設(shè)置為0,此時(shí)延遲100ms后再關(guān)閉加載框是沒(méi)有問(wèn)題的。