【问题标题】:Passing a value to the floating action button to be used in the bottom sheet将值传递给要在底部工作表中使用的浮动操作按钮
【发布时间】:2019-09-22 22:16:05
【问题描述】:

在此小部件中,选项卡在类型之间导航,如果有问题,它会转到指定的屏幕。如果是论坛,它会转到另一个论坛。问题是我需要将当前点击的类型传递给浮动操作按钮中的按下功能。但是浮动操作按钮位于脚手架主体之外。有没有办法将值传递给浮动操作按钮?


class TabScreen extends StatelessWidget {

  final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState();
  @override
  Widget build(BuildContext context) {
    final bool showfab = MediaQuery.of(context).viewInsets.bottom == 0.0;
    final AuthService authService = Provider.of<AuthService>(context);
 return StreamBuilder<List<String>>(
              stream: forumServices.forumsTypes$,
              builder: (context, snapshot) {
                if (!snapshot.hasData) {
                  return CircularProgressIndicator();
                }
                List<String> types = snapshot.data;
                num tabLen = types.length;

                return DefaultTabController(
                    length: tabLen,
                    child: Scaffold(
                      key: _scaffoldKey,

                      body: CustomScrollView(slivers: <Widget>[
                        SliverAppBar(
                          title: Text("kdkdkkd"),
                          bottom: TabBar(
                              tabs: types.map((String f) {
                            return Text(f);
                          }).toList()),
                        ),
                        SliverFillRemaining(
                          child: StreamBuilder<List<Forums>>(
                              stream: forumServices.forums$,
                              builder: (context, snap) {
                                if (!snap.hasData) {
                                  return CircularProgressIndicator();
                                }
                                final forum = snap.data;
                                return TabBarView(
                                  children: types.map((String type) {
                                    List<Forums> listofthistype =
                                        forum.where((Forums fo) {
                                      return fo.type == type;
                                    }).toList();

                                    final cards = listofthistype
                                        .map((thistype) => ForumCard(
                                              choosentype: thistype,
                                              forumServices: forumServices,
                                            ))
                                        .toList();

                                    return ListView(
                                      children: cards,
                                    );
                                  }).toList(),
                                );
                              }),
                        ),
                      ]),
                      floatingActionButton:
                        FloatingActionButton(
                              onPressed: () => _showBottom(),
                              tooltip: 'Increment',
                              child: Icon(Icons.add),
                            )

                    ));
              });

【问题讨论】:

  • 我也有同样的问题。我想将快照传递给浮动按钮 onPressed 函数。
  • 我使用了一个模型,从中获取所有数据,然后使用提供程序在按钮中调用它

标签: flutter parameter-passing floating-action-button scaffold


【解决方案1】:

删除DefaultTabController 小部件并改为创建您自己的TabController - 这允许您向TabController 添加一个侦听器,每次用户导航到不同的选项卡时都会触发该侦听器。您可以使用此机制获取与当前选项卡的索引关联的数据,例如类型。

这是您提供的代码,经过我上面提到的修改。类型存储在currentType 变量中,您可以在点击 Fab 时使用该变量。

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

class TabScreen extends StatefulWidget {
  @override
  _TabScreenState createState() => _TabScreenState();
}

class _TabScreenState extends State<TabScreen> with SingleTickerProviderStateMixin {
  final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
  TabController tabController;
  String currentType;

  @override
  Widget build(BuildContext context) {
    final bool showfab = MediaQuery.of(context).viewInsets.bottom == 0.0;
    final AuthService authService = Provider.of<AuthService>(context);

    return StreamBuilder<List<String>>(
      stream: forumServices.forumsTypes$,
      builder: (context, snapshot) {
        if (!snapshot.hasData) {
          return const CircularProgressIndicator();
        }
        List<String> types = snapshot.data;

        if (tabController == null) {
          currentType = types.first;

          tabController = TabController(length: types.length, vsync: this);
          tabController.addListener(() {
            currentType = types.elementAt(tabController.index);
          });
        }

        return Scaffold(
          key: _scaffoldKey,
          body: CustomScrollView(
            slivers: <Widget>[
              SliverAppBar(
                title: const Text("kdkdkkd"),
                bottom: TabBar(
                controller: tabController,
                tabs: types.map((String f) =>  Text(f)).toList()),
              ),
              SliverFillRemaining(
                child: StreamBuilder<List<Forums>>(
                  stream: forumServices.forums$,
                  builder: (context, snap) {
                    if (!snap.hasData) {
                      return const CircularProgressIndicator();
                    }
                    final forum = snap.data;

                    return TabBarView(
                      controller: tabController,
                      children: types.map((String type) {
                        List<Forums> listOfThisType = forum.where((Forums fo) => fo.type == type).toList();

                        return ListView(
                          children: listOfThisType.map((thisType) => ForumCard(
                            choosentype: thisType,
                            forumServices: forumServices,
                          )).toList(),
                        );
                      }).toList(),
                    );
                  },
                ),
              ),
            ],
          ),
          floatingActionButton: FloatingActionButton(
            onPressed: () => _showBottom(),
            tooltip: 'Increment',
            child: const Icon(Icons.add),
          ),
        );
      },
    );
  }
}

【讨论】:

    【解决方案2】:
    class Screen extends StatelessWidget {
      final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
      final GlobalKey<TabsWidgetState> _tabKey = GlobalKey<TabsWidgetState>();
    
      @override
      Widget build(BuildContext context) {
        return FutureBuilder<List<String>>(
            future: Future.delayed(
                const Duration(seconds: 1), () => ["Forum", "Question"]),
            builder: (context, snapshot) {
              if (!snapshot.hasData) {
                return CircularProgressIndicator();
              }
              List<String> types = snapshot.data;
              num tabLen = types.length;
    
              return Scaffold(
                  key: _scaffoldKey,
                  body: TabsWidget(key: _tabKey, tabLen: tabLen, types: types),
                  floatingActionButton: FloatingActionButton(
                    onPressed: () => print(_tabKey.currentState.currentQuestion),
                    tooltip: 'Increment',
                    child: Icon(Icons.add),
                  ));
            });
      }
    }
    
    class TabsWidget extends StatefulWidget {
      const TabsWidget({
        Key key,
        @required this.tabLen,
        @required this.types,
      }) : super(key: key);
    
      final num tabLen;
      final List<String> types;
    
      @override
      TabsWidgetState createState() => TabsWidgetState();
    }
    
    class TabsWidgetState extends State<TabsWidget> with SingleTickerProviderStateMixin{
    
       TabController _tabController;
       String currentQuestion;
    
      @override
      void initState() {
        _tabController = TabController(length: widget.tabLen, vsync: this)
        ..addListener(() {
          currentQuestion = widget.types[_tabController.index];
        });
    
      }
    
      @override
      Widget build(BuildContext context) {
        return CustomScrollView(slivers: <Widget>[
          SliverAppBar(
            title: Text("kdkdkkd"),
            bottom: TabBar(
                controller: _tabController,
                tabs: widget.types.map((String f) {
                  return Text(f);
                }).toList()),
          ),
          SliverFillRemaining(
            child: FutureBuilder(
                future: Future.delayed(const Duration(seconds: 1),
                        () => ["Forum", "Question"]),
                builder: (context, snap) {
                  if (!snap.hasData) {
                    return CircularProgressIndicator();
                  }
                  final forum = snap.data;
                  return TabBarView(
                    controller: _tabController,
                    children: widget.types.map((String type) {
                      List<String> listofthistype =
                      forum.where((String fo) {
                        return fo == type;
                      }).toList();
    
                      final cards = listofthistype
                          .map((thistype) => Text(thistype))
                          .toList();
    
                      return ListView(
                        children: cards,
                      );
                    }).toList(),
                  );
                }),
          ),
        ]);
      }
    }
    

    为简单起见,使用 futureBuilder 如果您的选项卡长度不是从快照中加载的,您可以避免使用全局键并在一开始就创建选项卡控制器。

    不要忘记进行空值检查。 Fab 将在数据加载之前显示。

    【讨论】:

      【解决方案3】:

      您可以将需要传递的数据存储在一个变量中,并在onPressedFloatingActionButton 中使用该变量。

      【讨论】:

        猜你喜欢
        • 2020-07-19
        • 2016-11-22
        • 2015-08-26
        • 1970-01-01
        • 1970-01-01
        • 2017-10-16
        • 1970-01-01
        • 2022-10-05
        • 1970-01-01
        相关资源
        最近更新 更多