【问题标题】:Pass dynamic data from Scaffold body to Navigation Drawer in Flutter (using Drawer as side sheet)将动态数据从 Scaffold 主体传递到 Flutter 中的 Navigation Drawer(使用 Drawer 作为侧页)
【发布时间】:2020-08-01 21:15:42
【问题描述】:

我正在开发一个支持多个计数器的计数器应用程序。由于颤振不提供侧页模式,我使用导航抽屉作为侧页。

我有一个脚手架,它的主体中有一个卡片的 GridView。这些卡每个都有一个名称和一个计数器值。每当点击其中一张卡片时,导航抽屉就会打开,它应该显示人的姓名和计数值。在此抽屉中,还有一个按钮,用于增加与单击的卡片对应的计数器值。但是,问题是,如何将数据从 Scaffold 主体传递到 Drawer?我可以使用Scaffold.of(context).openEndDrawer(); 以编程方式打开抽屉,但这不允许我将数据传递给它。

我也可以使用下面的代码,它确实允许我传递数据,但随后抽屉像页面一样打开并覆盖全屏。

Navigator.push(
  context, 
  MaterialPageRoute(
    builder: (context) => TurfDrawer(name: name, count: count)
  ));

所以基本上,我只想知道点击了哪张卡片并将其传递给抽屉。非常感谢所有帮助。

脚手架看起来像这样:

  @override
  Widget build(BuildContext context) {
    return Scaffold(

      // App bar
      appBar: AppBar(
        title: Text('Turflijst'),
        elevation: 0.0, 
        automaticallyImplyLeading: false,
        actions: <Widget>[
          IconButton(icon: Icon(Icons.settings), onPressed: null)
        ],
      ),

      // Drawer
      endDrawer: TurfDrawer(),

      // Body
      body: Builder(
        builder: (BuildContext context) {
          return Stack(
            alignment: AlignmentDirectional.topCenter,
            children: <Widget> [
              Container(
                color: primaryColor,
                height: (kEffectHeight - offset * 2.5).clamp(0.0, kEffectHeight),
              ),
              Positioned(
                child: Container(
                  margin: EdgeInsets.only(top: 70),
                  width: 1200.0,
                  child: GridView.count(
                    controller: scrollController,
                    crossAxisCount: 4,
                    crossAxisSpacing: 10,
                    mainAxisSpacing: 10,
                    childAspectRatio: 2,
                    children: <Widget>[
                      for (MapEntry entry in list.asMap().entries) 
                        TurfCard(index: entry.key, name: entry.value, count: count[entry.key])
                    ]

这是卡片:

class TurfCard extends StatefulWidget {

  final int index, count;
  final String name;
  TurfCard({
    Key key, 
    @required this.index, 
    @required this.name, 
    @required this.count
  }) : super(key: key);

  @override
  _TurfCardState createState() => _TurfCardState();
}

class _TurfCardState extends State<TurfCard> {

  @override
  Widget build (BuildContext context) {
    return GridTile(
      child: Card(
        elevation: 1.5,
        color: Colors.white,
        shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(15.0)),
        child: InkWell(
          splashColor: primaryColor.withAlpha(100),
          onTap: () {
            Scaffold.of(context).openEndDrawer();
            // Navigator.push(
            //   context, 
            //   MaterialPageRoute(
            //     builder: (context) => TurfDrawer()
            //   ));
            print('Card $widget.index tapped.');
          },

【问题讨论】:

    标签: flutter dart


    【解决方案1】:

    最后,我使用提供程序包中的 ChangeNotifier 解决了这个问题。每当单击 Card 时,ChangeNotifier 中的值都会更新并更新其侦听器。然后 Drawer 会监听这个 ChangeNotifier。

    【讨论】:

      【解决方案2】:

      这是一种解决方案:

      您将选定的索引保存为 ScaffoldWidget 类中的一个字段(无论您如何称呼它):

      class TurfCard extends StatefulWidget {
        final void Function() onTap;
      //...other properties
      }
      class _TurfCardState extends State<TurfCard> {
        @override
        Widget build(BuildContext context) {
          return SomeWidgets(
            child: InkWell(
              //...
              onTap: widget.onTap,
            ),
          );
        }
      }
      
      class HomePage extends StatelessWidget {
        int selectedIndex; //you can also save the index here and update it in onTap()
        @override
        Widget build(BuildContext context) {
          return Widget build(BuildContext context){
            return Scaffold(
              //...
                body: SomeWidgets(
                  //...
                for(MapEntry entry in list.asMap().entries)
                TurfCard(
                //some properties....
                onTap:(){
                     selectedIndex = entry.key;
                     Scaffold.of(context).openEndDrawer();
                    print('Card ${entry.key tapped.');
                     }
                 )
              ),
            ),
          };
        }
      }
      

      【讨论】:

      • 那么如何在我的 Drawer 小部件中使用这个 selectedIndex?
      • 将其存储在打开抽屉的小部件内的一个字段中,查看更新后的答案
      • 通过将 selectedIndex 设为静态并使用 HomePage.selectedIndex 在 Drawer 中访问它?这是在小部件之间传递数据的推荐方式吗?
      • 我没有在任何地方提到静态,看上面的代码它是一个简单的 int,对于更复杂的小部件之间共享数据的场景,您希望使用其他解决方案,例如提供程序包
      • 好吧,也许我太像 Flutter 菜鸟了,无法理解这一点。如果我的 Drawer 类不是静态的,我如何能够访问 selectedIndex?感谢您的帮助和耐心。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-01-05
      • 2018-11-07
      • 2022-01-15
      • 1970-01-01
      • 2019-06-30
      相关资源
      最近更新 更多