Flutter热重启与状态恢复插件phoenix_widgets的使用

发布于 1周前 作者 nodeper 来自 Flutter

Flutter热重启与状态恢复插件phoenix_widgets的使用

Phoenix Widgets

Phoenix Widgets 是一组用于创建各种界面组件的小部件集合。

开始使用

在你的 Flutter 项目的 pubspec.yaml 文件中添加以下依赖:

dependencies:
  ...
  phoenix_widgets: "^latestVersion"

然后导入该库:

import 'package:phoenix_widgets/phoenix_widgets.dart';

PhoenixCard

PhoenixCard 是一个可以创建卡片的小部件。

使用示例

PhoenixCard(
  title: Text(
    "Title with Image",
    style: Theme.of(context).textTheme.headline6,
  ),
  description: Text(
    "Description",
    style: Theme.of(context).textTheme.bodyText2,
  ),
  footer: Row(
    mainAxisAlignment: MainAxisAlignment.start,
    children: [
      const CircleAvatar(backgroundColor: Colors.red),
      const SizedBox(width: 8),
      Text(
        "Footer",
        style: Theme.of(context).textTheme.headline6,
      )
    ],
  ),
  image: Image.network(
    "https://images.contentstack.io/v3/assets/blt2a130c768c36b9df/blt5f384c7eb51e7cff/5f7d972ddf178b0ea98488e1/banner_sadaqah.jpg?auto=webp",
    fit: BoxFit.cover,
  ),
  onTap: () {},
),

可用参数

参数名 类型 是否必需 默认值
image Widget -
title Widget -
description Widget -
footer Widget -
width double double.maxFinite
padding EdgeInsets -
margin EdgeInsets const EdgeInsets.symmetric(horizontal: 16,vertical: 8)
onTap VoidCallback -
backgroundColor Color Colors.white
borderRadius double 4
footerSeparatorVisible bool false
imageHeight double 150.0
footerSeparator Widget -
label Widget -
enableShadow bool true
borderColor Color Colors.transparent
borderWidth double 1

PhoenixNavigationCard

PhoenixNavigationCard 是一个包含导航按钮的卡片小部件。

使用示例

PhoenixNavigationCard(
  isVisible: false,
  icon: SvgPicture.asset(
    "assets/education.svg",
    width: 46,
    height: 46,
  ),
  title: Text(
    "Title",
    style: Theme.of(context).textTheme.headline6,
  ),
  description: Text(
    "Lorem ipsum dolor sit amet, consectetur adipiscing elite!",
    style: Theme.of(context).textTheme.bodyText2,
  ),
  callback: () {},
  navigationText: Text(
    "Click Here",
    style: Theme.of(context).textTheme.bodyText2,
  ),
),

可用参数

参数名 类型 是否必需 默认值
icon Widget -
title Widget -
description Widget -
navigationText Widget Text(‘Click Me’)
isVisible bool true
width double double.maxFinite
padding EdgeInsets EdgeInsets.only(top: 16, bottom: 16)
callback VoidCallback -
backgroundColor Color Color(0x10C9B47D)
borderRadius double 4
icHeight double 46
icWidth double 46
icColor Color Colors.transparent
icBtnBackgroundColor Color Color(0x10C9B47D)
icBtnColor Color Color(0x1AC9B47D)
icBtnSize double 16

PhoenixBottomMenu

PhoenixBottomMenu 是一个底部导航栏的小部件。

使用示例

PhoenixBottomMenuUHF(
  selectedIndex: selectedIndex,
  navBarItems: [
    NavBarItem(
      name: "Home",
      image: SvgPicture.asset('assets/tab/home_default.svg'),
      selectedImage: SvgPicture.asset('assets/tab/home_selected.svg'),
    ),
    NavBarItem(
      name: "Feed",
      image: SvgPicture.asset('assets/tab/feed_default.svg'),
      selectedImage: SvgPicture.asset('assets/tab/feed_selected.svg'),
    ),
    NavBarItem(
      name: "Community",
      image: SvgPicture.asset('assets/tab/community_default.svg'),
      selectedImage: SvgPicture.asset('assets/tab/community_selected.svg'),
    ),
    NavBarItem(
      name: "Account",
      image: SvgPicture.asset('assets/tab/account_default.svg'),
      selectedImage: SvgPicture.asset('assets/tab/account_selected.svg'),
    ),
  ],
  selectedTabColor: Colors.red, ///可选
  unselectedTabColor: Colors.black54, ///可选
  onTabChange: (index) {
    setState(() {
      selectedIndex = index;
      _tabController!.jumpToPage(index);
    });
  },
)

可用参数

参数名 类型 是否必需 默认值
navBarItems List -
selectedTabColor Color Colors.red
unselectedTabColor Color Colors.black54
onTabChange Function -
backgroundColor Color -
elevation Double -
selectedIndex int 0

NavBarItem 的可用参数

参数名 类型 是否必需 默认值
name String -
image Widget -
selectedImage Widget -

PhoenixButton

PhoenixButton 是一个创建按钮的小部件。

使用示例

PhoenixButton(
  content: const Text(
    "Normal Button",
  ),
  margin: const EdgeInsets.only(
    left: 16,
    top: 16,
    right: 16,
  ),
  buttonElevation: 2,
  onPressed: () {
    ScaffoldMessenger.of(context).showSnackBar(
      const SnackBar(
        content: Text("Normal Button Clicked"),
      ),
    );
  },
  radius: 10,
),

可用参数

参数名 类型 是否必需 默认值
content Widget -
buttonMaterialStateProperty MaterialStateProperty -
buttonElevation Double 0.0
buttonColor Color -
textColor Color -
disableButtonColor Color -
radius Double -
margin EdgeInsets -
padding EdgeInsets -
height Double -
width Double double.infinity
borderSide BorderSide -
onPressed VoidCallback -

PhoenixProductTiles

PhoenixProductTiles 是一个创建产品图标的列表小部件。

使用示例

PhoenixProductTiles(
  onTap: (index) {},
  items: [
    PhoenixProductItem(
      "Tile 1",
      Image.asset(
        "assets/tile_1.png",
        width: 45,
        height: 45,
      )),
    PhoenixProductItem(
      "Tile 2",
      SvgPicture.asset(
        "assets/tile_2.svg",
        width: 45,
        height: 45,
      ),
      label: "Coming Soon"
    )
  ]
)

// 在非滑动父容器中使用
PhoenixProductTiles.box(
  onTap: (index) {},
  items: [
    PhoenixProductItem(
      "Tile 1",
      Image.asset(
        "assets/tile_1.png",
        width: 45,
        height: 45,
      )),
    PhoenixProductItem(
      "Tile 2",
      SvgPicture.asset(
        "assets/tile_2.svg",
        width: 45,
        height: 45,
      ),
      label: "Coming Soon"
    )
  ]
)

可用参数

PhoenixProductTiles

参数名 类型 是否必需 默认值
items List<PhoenixProductItem> -
onTap Function -
crossAxisCount int 4
labelBGColor Color null
labelTextColor Color null
radius double 20.0

PhoenixProductItem

参数名 类型 是否必需 默认值
title String -
icon Widget -
label String -
routeName String -

PhoenixGenericPopUp

PhoenixGenericPopUp 是一个显示带两个或一个按钮的弹窗函数。

使用示例

phoenixGenericPopUp(
  /// 必填
  context: context,
  popUpTitleWidget: Text(
    'Pop Up Two Button Title',
  ),
  popUpContentWidget: Text(
    "This is Pop Up One Button Message, Lorem ipsum dolor sit amet, consectetur adipiscing elit",
  ),

  /// 可选
  ensureWidget: Text(
    "Confirm",
    style: TextStyle(
      fontWeight: FontWeight.bold,
    ),
  ),
  cancelWidget: Text(
    "Cancel",
    style: TextStyle(
      color: Colors.red,
    ),
  ),
  // 如果 type != 1 弹窗不会因为点击确认按钮而消失
  type: 1,
  dismissOnOutsideTouch: false,
  ensureCallback: () {
    showSnackBar("Confirm Button Clicked");
  },
  cancelCallback: () {
    showSnackBar("Cancel Button Clicked");
  },
);

可用参数

参数名 类型 是否必需 默认值
context BuildContext -
popUpContentWidget Widget -
popUpTitleWidget Widget -
ensureWidget Widget Confirm
cancelWidget Widget -
type int 1
dismissOnOutsideTouch bool false
ensureCallback VoidCallback -
cancelCallback VoidCallback -

PhoenixPopUp

PhoenixPopUp 是一个显示带两个或一个按钮的弹窗函数。

使用示例

phoenixPopUp(
  context: context,
  title: 'Pop Up Two Button Title',
  description:
  "This is Pop Up One Button Message, Lorem ipsum dolor sit amet, consectetur adipiscing elit",
  primaryButtonLabel: 'Confirm',
  secondayButtonLabel: 'Cancel',
  type: 1,
  barrierDismissible: true,
  ensureCallback: () {
    showSnackBar("Confirm Button Clicked");
  },
  cancelCallback: () {
    showSnackBar("Cancel Button Clicked");
  },
);

可用参数

参数名 类型 是否必需 默认值
context BuildContext -
description String -
title String -
primaryButtonLabel String -
secondaryButtonLabel String -
type int 1
barrierDismissible bool false
direction PhoenixPopupDirection row
space double 16
elevation double 1.0
ensureCallback VoidCallback -
cancelCallback VoidCallback -

PhoenixWebview

PhoenixWebview 是一个创建网页视图的小部件。

使用示例

PhoenixWebview(url: "https://flutter.dev/", title: "Flutter Dev");

可用参数

参数名 类型 是否必需 默认值
url String -
title String -
isForRegistration bool false
isShowRefresh bool -
userAgent String -
bottomNavigationBar Widget -
refreshIcons Widget -
customJavaScripts String -
navigationDelegate Function -
isToRun List -
noInternetHandler Widget -
toolbarColor Color -
specialContainUrl List -
enableClearCacheInitDispose bool false

PhoenixBackButton

PhoenixBackButton 是一个创建返回按钮的小部件。

使用示例

PhoenixBackButton();

可用参数

参数名 类型 是否必需 默认值
color Color -
callback VoidCallback -
size double 28

PhoenixTitle

PhoenixTitle 是一个创建标题的小部件。

使用示例

PhoenixTitle(title: "Phoenix Title");

可用参数

参数名 类型 是否必需 默认值
title String -
fontSize double -
fontWeight FontWeight -
color Color -

PhoenixEmptyPage

PhoenixEmptyPage 是一个创建空页面的小部件。

使用示例

PhoenixEmptyPage(
  title: "No Data",
  pageImage: Image.asset(
    "assets/illustration.png",
  ),
  textStyle: const TextStyle(
    fontSize: 16.0,
    color: Color(0xff212124),
  ),
)

可用参数

参数名 类型 是否必需 默认值
title String -
pageImage Widget -
textStyle TextStyle fontSize: 16.0
color: Color(0xff212124)

PhoenixExpandableContentBlock

PhoenixExpandableContentBlock 是一个创建可展开内容块的小部件。文本内容中的 URL 可以点击,并且可以通过长按复制文本内容。

使用示例

PhoenixExpandableContentBlock(
  text: "Flutter is Google’s portable UI toolkit. Visit https://flutter.dev to learn more.",
  style: Theme.of(context).textTheme.bodyText2,
  urls: [Url("https://flutter.dev", [47, 66])],
  shortenButtonLabel: "[See less]",
  expandButtonLabel: "[See more]"
)

可用参数

参数名 类型 是否必需 默认值
text String -
style TextStyle -
urls List -
shortenButtonLabel String -
expandButtonLabel String -
maxLines int 6
expandableStateChangeCallback VoidCallback -
textCopiedCallback VoidCallback -

PhoenixBottomSheet

PhoenixBottomSheet 是一个显示底部弹出框的小部件。

使用示例

// 包装在 StatefulWidget 中
final PhoenixBottomSheet _bottomSheetHowItWorks = PhoenixBottomSheet();

@override
Widget build(BuildContext context) {
  return Scaffold(
    backgroundColor: Colors.white,
    appBar: AppBar(
      title: const Text('Phoenix Bottom Sheet Sample'),
    ),
    body: Center(
      child: ElevatedButton(
        child: const Text("Show All Products"),
        onPressed: () {
          _bottomSheetHowItWorks(
            context,
            title: 'Title of bottom Sheet',
            children: [
              for (final item in _items)
                Padding(
                  padding: const EdgeInsets.symmetric(
                    vertical: 12,
                    horizontal: 20,
                  ),
                  child: Row(
                    children: [
                      item.icon,
                      const SizedBox(height: 16),
                      Expanded(
                        child: Column(
                          crossAxisAlignment: CrossAxisAlignment.start,
                          children: [
                            Text(
                              item.title,
                              style: const TextStyle(
                                color: Color(0xFF212124),
                                fontSize: 16,
                                fontWeight: FontWeight.w500,
                              ),
                            ),
                            Text(
                              'Description ${item.title}',
                              style: const TextStyle(
                                color: Color(0xFF212124),
                                fontSize: 14,
                                fontWeight: FontWeight.normal,
                              ),
                            ),
                          ],
                        ),
                      )
                    ],
                  ),
                )
            ],
          );
        },
      ),
    ),
  );
}

// 示例数据
final List<PhoenixProductItem> _items = [
  PhoenixProductItem(
    "Tile 1",
    Image.asset(
      "assets/tab_home.png",
      width: 45,
      height: 45,
    )),
  PhoenixProductItem(
    "Tile 2",
    Image.asset(
      "assets/tab_home.png",
      width: 45,
      height: 45,
    )),
  PhoenixProductItem(
    "Tile 3",
    Image.asset(
      "assets/tab_home.png",
      width: 45,
      height: 45,
    )),
  PhoenixProductItem(
    "Tile 4",
    Image.asset(
      "assets/tab_home.png",
      width: 45,
      height: 45,
    )),
  PhoenixProductItem(
    "Tile 5",
    Image.asset(
      "assets/tab_home.png",
      width: 45,
      height: 45,
    )),
  PhoenixProductItem(
    "Tile 6",
    Image.asset(
      "assets/tab_home.png",
      width: 45,
      height: 45,
    )),
  PhoenixProductItem(
    "Tile 7",
    Image.asset(
      "assets/tab_home.png",
      width: 45,
      height: 45,
    ),
    label: "Coming Soon"),
  PhoenixProductItem(
    "Tile 8",
    Image.asset(
      "assets/tab_home.png",
      width: 45,
      height: 45,
    ),
    label: "Coming Soon"),
];

可用参数

参数名 类型 是否必需 默认值
context BuildContext -
title String -
children List -
margin EdgeInsets -
padding EdgeInsets -
elevation double 0

PhoenixBottomSheetTile

PhoenixBottomSheetTile 是一个显示底部弹出框的小部件,其中包含图块。

使用示例

// 包装在 StatefulWidget 中
final PhoenixBottomSheetTile _bottomSheetHowItWorks = PhoenixBottomSheetTile();

@override
Widget build(BuildContext context) {
  return Scaffold(
    backgroundColor: Colors.white,
    appBar: AppBar(
      title: const Text('Phoenix Bottom Sheet Tile Sample'),
    ),
    body: Center(
      child: ElevatedButton(
        child: const Text("Show All Products"),
        onPressed: () {
          _bottomSheetHowItWorks(
            context,
            spacing: const EdgeInsets.only(bottom: 16.0),
            padding: const EdgeInsets.only(
              top: 16,
              bottom: 58,
            ),
            title: 'Title of bottom sheet',
            style: const TextStyle(
              color: Color(0xFF212124),
              fontSize: 16,
              fontWeight: FontWeight.w500,
            ),
            child: CustomScrollView(
              shrinkWrap: true,
              slivers: [
                PhoenixProductTiles(
                  onTap: (index) {},
                  items: _items,
                )
              ],
            ),
          );
        },
      ),
    ),
  );
}

// 示例数据
final List<PhoenixProductItem> _items = [
  PhoenixProductItem(
    "Tile 1",
    SvgPicture.asset(
      "assets/education.svg",
      width: 46,
      height: 46,
    )),
  PhoenixProductItem(
    "Tile 2",
    SvgPicture.asset(
      "assets/education.svg",
      width: 46,
      height: 46,
    )),
  PhoenixProductItem(
    "Tile 3",
    SvgPicture.asset(
      "assets/education.svg",
      width: 46,
      height: 46,
    ),
    label: "Coming Soon"),
  PhoenixProductItem(
    "Tile 4",
    SvgPicture.asset(
      "assets/education.svg",
      width: 46,
      height: 46,
    ),
    label: "Coming Soon"),
  PhoenixProductItem(
    "Tile 5",
    Image.asset(
      "assets/tab_home.png",
      width: 45,
      height: 45,
    )),
  PhoenixProductItem(
    "Tile 6",
    Image.asset(
      "assets/tab_home.png",
      width: 45,
      height: 45,
    )),
  PhoenixProductItem(
    "Tile 7",
    Image.asset(
      "assets/tab_home.png",
      width: 45,
      height: 45,
    ),
    label: "Coming Soon"),
  PhoenixProductItem(
    "Tile 8",
    Image.asset(
      "assets/tab_home.png",
      width: 45,
      height: 45,
    ),
    label: "Coming Soon"),
];

可用参数

参数名 类型 是否必需 默认值
context BuildContext -
title String -
style TextStyle TextStyle(color: Color(0xFF212124), fontSize: 16,fontWeight: FontWeight.w500,)
spacing EdgeInsetsGeometry EdgeInsets.only(bottom: 16.0)
padding EdgeInsetsGeometry EdgeInsets.only(top: 16, bottom: 58,)
child Widget -

PhoenixShimmer

PhoenixShimmer 是一个显示加载效果的小部件。

使用示例

ShimmerWidget.rectangular(
  height: 10,
  width: 100,
  baseColor: Colors.red,
)

ShimmerWidget.circular(
  height: 100,
  width: 100,
  baseColor: Colors.red,
)

可用参数

参数名 类型 是否必需 默认值
width double double.infinity
height double -
baseColor Color Color(0xFFE0E0E0)
shapeBorder ShapeBorder RoundedRectangleBorder()
CircleBorder()

PhoenixBanner

PhoenixBanner 是一个显示轮播广告的小部件。

使用示例

PhoenixBanner(
  listSlider: [
    'https://picsum.photos/820/360',
    'https://picsum.photos/820/360',
    'https://picsum.photos/820/360',
    'https://picsum.photos/820/360'
  ],
  onEvent: (GestureEvent event, index) {
    if (event == GestureEvent.onSwipe) {
      print('onSwipe');
    } else {
      print('onTap');
    }
  },
)

可用参数

参数名 类型 是否必需 默认值
listSlider List -
onEvent void Function(GestureEvent event, int index) -
carouselDurationMs int? 3000
activeColour Color Colors.white
inActiveColour Color Colors.black.withOpacity(0.25)
bannerHeight double 170.0
viewportFraction double 0.9
fit BoxFit BoxFit.cover
indicatorPosition IndicatorPosition {top, bottom} IndicatorPosition.bottom

PhoenixSearchbar

PhoenixSearchbar 是一个搜索框的小部件。

使用示例

PhoenixSearchbar(
  hintText: "Search",
  padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
  enabled: true,
  actionWidget: TextButton(
    onPressed: () {
      showSnackBar("Cancel");
    },
    child: const Text(
      "Cancel",
      style: TextStyle(
        color: Color(0xFF67C1BF),
        fontSize: 16,
        fontWeight: FontWeight.w500,
      ),
    ),
  ),
  radius: 24,
  onChanged: (value) {
    setState(() {
      result = value;
    });
  },
),

可用参数

参数名 类型 是否必需 默认值
hintText String “”
fillColor Color Color(0xFFF9F9F9)
borderColor Color Color(0xFFF9F9F9)
enabled bool true
isFocus bool true
radius double 0
spaceBetween double -
actionWidget Widget -
searchIcon Widget Icon(Icons.search, size: 24, color: Color(0xff75767A),)
textEditingController TextEditingController TextEditingController()
hintTextStyle TextStyle TextStyle(color: Color(0xff75767A), fontSize: 14,)
padding EdgeInsets EdgeInsets.zero
onWidgetTap VoidCallback -
onChanged Function(String) -

PhoenixExpandableList

PhoenixExpandableList 是一个带有可展开功能的列表小部件。

使用示例

PhoenixExpandableList(
  expendableData: expendableData[i],
  margin: contentMargin ?? const EdgeInsets.only(top: 8, bottom: 16),
  contentMargin: const EdgeInsets.all(16),
  padding: const EdgeInsets.all(16),
  expandColor: Colors.white,
  shrinkColor: const Color(0xffF9F9F9),
  radius: 5,
  shrinkImage: SvgPicture.asset("assets/ic_minus.svg"),
  expandImage: SvgPicture.asset("assets/ic_plus.svg"),
  showData: expendableData[i].show,
  callback: () {
    setState(() {
      expendableData[i].show = !expendableData[i].show;
    });
  },
)

可用参数

参数名 类型 是否必需 默认值
expendableData ExpendableData -
margin EdgeInsetsGeometry EdgeInsets.all(16)
contentMargin EdgeInsetsGeometry EdgeInsets.only(top: 8, bottom: 16)
padding EdgeInsetsGeometry EdgeInsets.all(16)
titlePadding EdgeInsetsGeometry EdgeInsets.zero
expandColor Color Colors.white
shrinkColor Color Colors.grey
radius double -
shrinkImage Widget Icon(Icons.add)
expandImage Widget Icon(Icons.minimize)
showData bool false
callback VoidCallback -

PhoenixWarning

PhoenixWarning 是一个显示警告的小部件。

使用示例

PhoenixWarning(
  warningVisibility: true,
  messageWidget: const Text(
    "This is example of warning. Put any text here",
    style: TextStyle(
      color: Colors.black,
      fontSize: 10,
      fontWeight: FontWeight.normal,
    ),
  ),
  errorWidget: const Icon(Icons.error_outline, color: Colors.black),
  borderColor: Colors.red.withOpacity(.8),
  backgroundColor: Colors.red.withOpacity(.6),
  margin: const EdgeInsets.only(top: 8),
  padding: const EdgeInsets.all(8),
  radius: 5,
  spacerHeight: 100
)

可用参数

参数名 类型 是否必需 默认值
warningVisibility bool -
messageWidget Widget -
errorWidget Widget -
borderColor Color -
backgroundColor Color -
margin EdgeInsetsGeometry -
padding EdgeInsetsGeometry -
radius double -
spacerHeight double -

PhoenixListGroup

PhoenixListGroup 是一个生成菜单列表的小部件,其中包含子菜单。

使用示例

PhoenixListGroup(
  groupList: _sampleGrouping,
),

// 示例数据
Map<String, List<DataHelper>> _sampleGrouping = {
  'Data 1': [
    DataHelper(
      title: 'Title Data 2.1',
      desc: 'Description Data 2.1',
      isSelected: true,
      isVisible: false),
    DataHelper(
      title: 'Title Data 2.2',
      desc: 'Description Data 2.2',
      isSelected: true,
      isVisible: true),
    DataHelper(
      title: 'Title Data 2.3',
      desc: 'Description Data 2.3',
      isSelected: true,
      isVisible: true),
  ],
  'Data 2': [
    DataHelper(
      title: 'Title Data 2.1',
      desc: 'Description Data 2.1',
      isSelected: true,
      isVisible: true),
    DataHelper(
      title: 'Title Data 2.2',
      desc: 'Description Data 2.2',
      isSelected: true,
      isVisible: false),
    DataHelper(
      title: 'Title Data 2.3',
      desc: 'Description Data 2.3',
      isSelected: true,
      isVisible: true),
  ]
}

可用参数

参数名 类型 是否必需 默认值
groupList Map<String, List<DataHelper>> -
hideLastDivider bool false
titlePadding EdgeInsets EdgeInsets.all(8)

PhoenixTextField

PhoenixTextField 是一个创建文本输入框的小部件。

使用示例


更多关于Flutter热重启与状态恢复插件phoenix_widgets的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter热重启与状态恢复插件phoenix_widgets的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是如何在Flutter项目中使用phoenix_widgets插件来实现热重启与状态恢复的示例代码。phoenix_widgets插件允许你的应用在遇到未捕获异常时自动重启,同时尝试恢复先前的状态。

1. 添加依赖

首先,你需要在pubspec.yaml文件中添加phoenix_widgets依赖:

dependencies:
  flutter:
    sdk: flutter
  phoenix_widgets: ^0.12.0  # 请确保使用最新版本

然后运行flutter pub get来安装依赖。

2. 创建自动重启的根Widget

接下来,在你的应用入口文件(通常是main.dart)中,使用AutomaticKeepAliveClientMixinPhoenix来创建一个能够自动重启的根Widget。

import 'package:flutter/material.dart';
import 'package:phoenix_widgets/phoenix_widgets.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Phoenix(
      child: MaterialApp(
        title: 'Flutter Demo',
        theme: ThemeData(
          primarySwatch: Colors.blue,
        ),
        home: MyHomePage(),
      ),
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> with AutomaticKeepAliveClientMixin {
  int _counter = 0;

  void _incrementCounter() {
    setState(() {
      _counter++;
      // 模拟一个未捕获的异常
      if (_counter == 5) {
        throw UnimplementedError('Simulated crash');
      }
    });
  }

  @override
  Widget build(BuildContext context) {
    super.keepAlive();
    return Scaffold(
      appBar: AppBar(
        title: Text('Flutter Demo Home Page'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'You have pushed the button this many times:',
            ),
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.headline4,
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ),
    );
  }

  @override
  bool get wantKeepAlive => true;
}

3. 运行应用

现在你可以运行你的Flutter应用。当你点击浮动操作按钮(FAB)5次时,应用会抛出一个未捕获的异常并崩溃。但由于我们使用了Phoenix,应用会自动重启,并且状态(除了计数器,因为我们在异常发生时重置了状态)会被恢复。

注意事项

  • 状态恢复phoenix_widgets会自动尝试恢复Widget树的状态,但某些复杂的状态(如BLoC、Provider状态等)可能需要额外的逻辑来恢复。
  • 异常处理:在生产环境中,你应该有更健壮的异常处理机制,而不仅仅是依赖自动重启。
  • 持久化数据:对于需要持久化的数据(如用户输入、应用设置等),应该使用Flutter的持久化存储解决方案(如SharedPreferences、SQLite等)。

这个示例展示了如何使用phoenix_widgets来实现热重启和基本的状态恢复。根据你的应用需求,你可能需要调整或扩展这个基础实现。

回到顶部