【问题标题】:Position a widget on the top of the next screen?在下一个屏幕的顶部放置一个小部件?
【发布时间】:2021-08-28 14:48:30
【问题描述】:

我有一个 SingleChildScrollView,它的 Column 小部件有很多孩子。我想在“下一个屏幕上”保留一组按钮(例如“PageBreak 小部件”)。

我已经尝试过了,但它会产生异常,因为您只应该使用带有 Stack Widget(而不是 Column Widget)的 Positioned 小部件:

                      if (btnset is Spacer)
                        Positioned(
                            top: height,
                            child: SizedBox(
                                key: GlobalKey(
                                  debugLabel: "NEXTSCREEN",
                                ),
                                height: height / 2))

height/2太大了……旋转屏幕时效果不对……

完整的 UI 部分(查找“NEXTSCREEN”):

    return Scaffold(
      floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
      floatingActionButton: Column(
          crossAxisAlignment: CrossAxisAlignment.center,
          mainAxisSize: MainAxisSize.max,
          children: [
            SizedBox(height: 80),
            if (_scrollController.hasClients && _scrollController.offset > 0)
              FloatingActionButton(
                  backgroundColor: Colors.white,
                  foregroundColor: Colors.blue,
                  child: Icon(Icons.arrow_upward),
                  mini: true,
                  heroTag: null,
                  onPressed: () {
                    if (_scrollController.hasClients)
                      _scrollController.animateTo(
                          _scrollController.offset -
                              _scrollController.position.viewportDimension,
                          duration: Duration(milliseconds: 500),
                          curve: Curves.ease);
                  }),
            Spacer(),
            if (_scrollController.hasClients &&
                _scrollController.offset <
                    _scrollController.position.maxScrollExtent)
              FloatingActionButton(
                  backgroundColor: Colors.white,
                  foregroundColor: Colors.blue,
                  mini: true,
                  heroTag: null,
                  child: Icon(Icons.arrow_downward),
                  onPressed: () {
                    if (_scrollController.hasClients)
                      _scrollController.animateTo(
                          _scrollController.offset +
                              _scrollController.position.viewportDimension,
                          duration: Duration(milliseconds: 500),
                          curve: Curves.ease);
                  }),
          ]),
      appBar: AppBar(
          title: Text(meshTag +
                  data['Name']
                      .strval() /*+
              "  " +
              StatusWord(data['Alarms'].val).toString()*/
              ),
          actions: [
            StatusWordWidget(
              data['Alarms'].val,
              short: true,
              direction: Axis.horizontal,
            ),
          ]),
      //drawer: Drawer(), //You do this, the back arrow goes away...
      body: !initialized
          ? Center(
              child:
                  CircularProgressIndicator()) //Circle of Death while we connect
          : Scrollbar(
              thickness: 8.0,
              isAlwaysShown: true,
              child: SingleChildScrollView(
                controller: _scrollController,
                child: Column(
                  mainAxisSize: MainAxisSize.min,
                  mainAxisAlignment: MainAxisAlignment.center,
                  verticalDirection: VerticalDirection.down,
                  children: <Widget>[
                    Container(
                        margin: EdgeInsets.fromLTRB(
                            0, 0, 10, 2), //Make room for scroll bar!
                        child: headerRow()),
                    Row(
                        mainAxisAlignment: MainAxisAlignment.center,
                        mainAxisSize: MainAxisSize.min,
                        children: <Widget>[
                          RotatedBox(
                              quarterTurns: -1,
                              child: ConstrainedBox(
                                  constraints: BoxConstraints.tightFor(
                                      height: 50, width: chartHeight),
                                  child: Center(
                                      child: SliderTheme(
                                          data: SliderThemeData(
                                              trackShape: CustomTrackShape()),
                                          child: Slider(
                                              value: localset * 1.0,
                                              max: maxy,
                                              min: miny,
                                              onChanged: (double value) {
                                                setState(() {
                                                  localset = value.toInt();
                                                });
                                              }))))),
                          Expanded(child: chartwidget)
                        ]),
                    if (localset != data['Setpoint'].val)
                      ElevatedButton(
                        child: Text('Set Setpoint to: ' + localset.toString()),
                        onPressed: (localset == data['Setpoint'].val)
                            ? null
                            : () {
                                //Write Value to Ble.
                                setState(() {
                                  data['Setpoint'].val = localset;
                                  data['Setpoint'].bttx();
                                });
                              },
                      ),
                    Divider(),
                    for (var btnset in mainButtons) ...[
                      if (btnset is Spacer)
                        SizedBox(
                            key: GlobalKey(
                              debugLabel: "NEXTSCREEN",
                            ),
                            height: height / 3)
                      else ...[btnset, Divider()]
                    ],
                    Divider(),
                    GestureDetector(
                      child: Divider(
                        thickness: 8,
                      ),
                      onLongPress: () {
                        showdev = true;
                      },
                    ),
                    if (showdev) ...{
                      ElevatedButton(
                          onPressed: () {
                            //Load the log
                            loadlogtext();
                          },
                          child: Text("Read")),
                      ConstrainedBox(
                          constraints: BoxConstraints(minWidth: 300),
                          child: Text(logtext)),
                      Divider(),
                      //ToDo: A debug datatable with all vars.
                      DataTable(
                        showCheckboxColumn: false,
                        columns: [
                          DataColumn(
                            label: Text("Name"),
                            numeric: false,
                            tooltip: "Name of parameter",
                          ),
                          DataColumn(
                            label: Expanded(child: Text("Value")),
                            numeric: true,
                            tooltip: "Signal Strength",
                          ),
                        ],
                        rows: DeviceData.entries
                            .map(
                              (item) => DataRow(
                                  onSelectChanged: (bool? selected) {
                                    print('Picked ${item.name}');
                                  },
                                  cells: [
                                    DataCell(Container(
                                      //width: 120,
                                      child: Text(item.name),
                                    )),
                                    DataCell(
                                      Container(
                                          width: 40,
                                          child: Text((item.isnum
                                              ? item.val.toString()
                                              : item.str == null
                                                  ? "<null>"
                                                  : item.str)!)),
                                    ),
                                  ]),
                            )
                            .toList(),
                      ),
                      Divider()
                    },
                    Row(
                      mainAxisAlignment: MainAxisAlignment.center,
                      mainAxisSize: MainAxisSize.min,
                      children: <Widget>[
                        Padding(
                          padding: EdgeInsets.all(20.0),
                          child: OutlinedButton(
                            child: Text('Back'),
                            onPressed: () {
                              Navigator.pop(context);
                            },
                          ),
                        ),
                      ],
                    ),
                    ConstrainedBox(
                        constraints: BoxConstraints(
                            minHeight: 40)) //Keep the button off the bottom...
                  ],
                ),
              )),
    );
  }
}

【问题讨论】:

  • 分享完整代码
  • 完成...似乎不太清楚。

标签: flutter


【解决方案1】:

如果你想改变一个小部件在堆栈外的位置,你可以使用Transform.translate()。但是,这不是您的情况最理想的解决方案。

由于您使用的是脚手架,因此您可以将appBar 设为带有AppBar() 的列,然后是您想要保留在屏幕上的小部件,或者将小部件放在bottomNavigationBar() 中。也可以使用CustomScrollView(),因为您可以拥有一个滚动应用栏,当您滚动页面时会发生变化(在此处阅读更多信息https://api.flutter.dev/flutter/widgets/CustomScrollView-class.html)或NestedScrollView(),如果您觉得它更适合您的需要(在此处阅读更多信息@ 987654322@).

使用Transform.translate() 小部件几乎从来都不是您正在做的事情的好选择,因为它实施起来更痛苦,并且适用于更小种类的屏幕。它也是“重新发明轮子”,因为 Flutter 已经提供了很多有用的方法来实现这一点,所以我建议您查看上面的小部件并尝试找到最适合您需求的小部件。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多