[英]How to implement Popup with Flutter?
我有一個 Flutter 應用程序,其屏幕使用數組有條件地呈現。 無論如何,我需要有一個像這樣的彈出屏幕:
如果已將我所有的“彈出屏幕”存儲在一個數組中,並將主屏幕和彈出屏幕呈現在一個堆棧中。 我不知道這是否是最好的解決方案,我想我會遇到性能問題。
這是PopupContainer
類,這個 Widget 在每個 Popup Screen 上呈現,子元素作為 content 傳遞:
class PopupContainer extends StatefulWidget {
final Widget? child;
const PopupContainer({
Key? key,
this.child,
}) : super(key: key);
@override
State<PopupContainer> createState() => _PopupContainerState();
}
class _PopupContainerState extends State<PopupContainer> {
@override
Widget build(BuildContext context) {
final height = MediaQuery.of(context).size.height;
return Consumer<ScreenManager>(
builder: (context, manager, child) => Stack(
alignment: Alignment.bottomCenter,
children: [
BackdropFilter(
filter: ImageFilter.blur(sigmaX: 6, sigmaY: 6),
child: Container(
decoration: BoxDecoration(color: Colors.white.withOpacity(0.0)),
),
),
Container(
height: height * 0.8,
width: double.infinity,
padding: const EdgeInsets.all(32),
decoration: const BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(16),
topRight: Radius.circular(16),
),
boxShadow: [
BoxShadow(
blurRadius: 37,
spreadRadius: 0,
color: Color.fromRGBO(28, 48, 72, 0.24),
),
],
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
alignment: Alignment.topRight,
child: ElevatedButton(
style: ElevatedButton.styleFrom(
padding: EdgeInsets.zero,
primary: Colors.transparent,
shadowColor: Colors.transparent,
),
onPressed: () => manager.closePopup(),
child: SvgPicture.asset('assets/close.svg'),
),
),
widget.child ?? const SizedBox.shrink(),
],
),
),
],
),
);
}
}
消費者用於處理屏幕狀態:
enum ScreensName {
homeScreen,
favoriteProductsScreen,
archivedListsScreen,
recipesScreen,
}
enum PopupsName {
newProductPopup,
archivedListPopup,
editProductPopup,
newRecipePopup,
}
const screens = <ScreensName, Widget>{
ScreensName.homeScreen: HomeScreen(),
ScreensName.favoriteProductsScreen: FavoriteProductsScreen(),
ScreensName.archivedListsScreen: ArchivedListsScreen(),
ScreensName.recipesScreen: RecipesScreen(),
};
const popups = <PopupsName, Widget>{
PopupsName.newProductPopup: NewProductPopup(),
};
class ScreenManager extends ChangeNotifier {
static ScreensName screenName = ScreensName.homeScreen;
static PopupsName? popupName = PopupsName.newProductPopup;
get currentScreen => screens[screenName];
get currentPopup => (popups[popupName] ?? Container());
/// Open the given popup.
void openPopup(PopupsName newPopupName) {
popupName = newPopupName;
notifyListeners();
}
/// Closes the current popup.
void closePopup() {
popupName = null;
notifyListeners();
}
/// Change the screen.
void setScreen(ScreensName newScreenName) {
screenName = newScreenName;
notifyListeners();
}
}
最后,主要的組件構建方法(我也有一些主題樣式,但在這里沒用):
Widget build(BuildContext context) {
DatabaseHelper.initDb();
return Consumer<ScreenManager>(
builder: (context, screenManager, child) => Material(
child: MaterialApp(
title: _title,
theme: _customTheme(),
home: Stack(
alignment: Alignment.bottomCenter,
children: <Widget>[
screenManager.currentScreen,
screenManager.currentPopup,
],
),
),
),
);
}
PS:我是一名網絡開發人員,所以我知道主要的編程原則,但 Dart 和移動開發對我來說是全新的。 另外,我可以和你分享我的代碼,但是,這個項目被分成文件,在帖子中會占用太多空間。 問你是否需要它!
也許更簡單的解決方案是在需要觸發彈出窗口的地方使用 showDialog 函數。 查看文檔https://api.flutter.dev/flutter/material/showDialog.html
showDialog(context: context, builder: (context) => AlertDialog(title: Text('Title'), content: Text('Here content'),));
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.