首页 > 解决方案 > 将变量从 MaterialPageRoute 传递到自定义小部件

问题描述

一点背景知识:Flutter noob here,试图构建一个添加到收藏夹功能。项目列表位于我在 FirstScreen 上使用 http 访问的 PHP/MySQL 数据库中。当用户点击其中一个列表项时,他们会被重定向到 SecondScreen,我使用 MaterialPageRoute 传递“itemId”,它有一个“添加到收藏夹”按钮。收藏项目的“itemId”使用 sqflite 存储在本地。我可以使用 StatefulWidget 访问“itemId”,但我没有成功尝试创建一个管理无状态小部件的自定义 Stateful 小部件,就像在这个Flutter 交互性示例中一样,即我无法从自定义 Stateful 访问“itemId”小部件。

代码片段:

MaterialPageRoute(
  builder: (context) => SecondScreen(
  itemId: item[index].itemId,

我的 sqflite checkFavourited 功能:

Future<bool> checkFavourited(String itemId) async {
        Database db = await instance.database;
        var bookmarked = await db.query(table,
            where: 'itemId = ?',
            whereArgs: [itemId]);
        return bookmarked.isEmpty ? false : true;
      }

工作状态小部件:

 bool _isFavourited = false;

  void isFavourited() async {
    final isFavourited =
        await DatabaseHelper.instance.checkFavourited(widget.itemId);
    setState(() {
      _isFavourited = isFavourited;
    });
  }

但是我在 StatelessWidget 中的尝试失败了。到目前为止,我有:

class SecondScreen extends StatelessWidget {
  final String itemId;
  SecondScreen({
    Key key,
    @required this.itemId,

我收到以下错误消息:

The getter 'itemId' isn't defined for the type 'FavouritedButton'.

当我尝试这样做时:

class FavouritedButton extends StatefulWidget {
  @override
  _FavouritedButtonState createState() => _FavouritedButtonState();
}

class _FavouritedButtonState extends State<FavouritedButton> {
  bool _isFavourited = false;

  void isFavourited() async {
    final isFavourited =
    await DatabaseHelper.instance.checkBookmark(widget.itemId);
    setState(() {
      _isFavourited = isFavourited;
    });
  }
  @override
  Widget build(BuildContext context) {
    return IconButton(
      icon: isFavourited
          ? Icon(Icons.bookmark)
          : Icon(
              Icons.bookmark_border,
            ),

我已经阅读了Flutter 的简单应用程序状态管理状态管理方法列表文章,我可能错了,但有没有比 Provider 或 FutureBuilder 更简单的解决方案?

我知道这是一篇很长的帖子,如果有人能给我一些指示,我将不胜感激。提前致谢!

标签: flutterbookmarksfavoritesstatefulwidgetstatelesswidget

解决方案


干净的代码方法,通过将您的小部件重建隔离为尽可能窄,您正在做正确的事情,但需要移动id到您的有状态小部件。

class FavouritedButton extends StatefulWidget {
final String itemId;
  FavouritedButton({required this.itemId});

  @override
  _FavouritedButtonState createState() => _FavouritedButtonState();
}
class _FavouritedButtonState extends State<FavouritedButton> {
//add initState here, and keep the rest of your widget as it is.
 @override
  void initState() {
  isFavourited();
    super.initState();
  }

然后在您的无状态小部件中:

class SecondScreen extends StatelessWidget {
 final String itemId;

  const SecondScreen({Key? key, required this.itemId}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    
    return Column(children:[
     Text('write some text about your widget or $itemId'),
     FavouritedButton(itemId:itemId)
  ]);
  }
}

这只会重建您最喜欢的按钮。


推荐阅读