Flutter 如果需要,是否将中间元素换行到新行?

Flutter 如果需要,是否将中间元素换行到新行?,flutter,flutter-layout,flutter-widget,flutter-row,Flutter,Flutter Layout,Flutter Widget,Flutter Row,我在多页表单的底部有一个导航栏,带有返回或前进按钮,以及当前页面的指示器 现在,我将指示器放置在另一个行上方的行中,该行包含按钮,如下所示: 这是可行的,即使在小尺寸的显示器上也可以。但是,如果有足够的空间,我宁愿将指示器与按钮放在同一行上,如下图所示(除了指示器未居中): 问题是,对于某些设备来说,这可能太宽了,特别是如果页面不止几页的话。在这种情况下,我希望页面指示器或按钮“换行”到新行,如当前设计中所示 将所有内容放在换行中很容易,但这将使下一个按钮换行,而不是页面指示器,因为这是最后

我在多页表单的底部有一个导航栏,带有返回或前进按钮,以及当前页面的指示器

现在,我将指示器放置在另一个
上方的
中,该行包含按钮,如下所示:

这是可行的,即使在小尺寸的显示器上也可以。但是,如果有足够的空间,我宁愿将指示器与按钮放在同一行上,如下图所示(除了指示器未居中):

问题是,对于某些设备来说,这可能太宽了,特别是如果页面不止几页的话。在这种情况下,我希望页面指示器或按钮“换行”到新行,如当前设计中所示

将所有内容放在
换行
中很容易,但这将使
下一个
按钮换行,而不是页面指示器,因为这是最后一个元素


如果需要,是否有一种简单的方法可以将中间元素换行到新行上?还是必须求助于手动计算尺寸和创建两种不同布局的魔法?

最简单的解决方案是添加不可见包裹以计算高度

导入“包装:颤振/材料.省道”;
void main()=>runApp(MyApp());
类MyApp扩展了无状态小部件{
@凌驾
小部件构建(构建上下文){
返回材料PP(
标题:“颤振演示”,
主题:主题数据(
主样本:颜色。蓝色,
),
家:脚手架(
正文:安全区(
子:MyHomePage(),
),
),
);
}
}
类MyHomePage扩展StatefulWidget{
@凌驾
_MyHomePageState createState()=>\u MyHomePageState();
}
类_MyHomePageState扩展状态{
int currentPageIndex=1;
int pageCount=8;
@凌驾
小部件构建(构建上下文){
返回列(
儿童:[
扩大(
儿童:中心(
子:列(
mainAxisSize:mainAxisSize.min,
儿童:[
正文(
currentPageIndex.toString(),
),
划船(
mainAxisSize:mainAxisSize.min,
儿童:[
升起的按钮(
子项:文本(“+1页”),
按下时:()=>setState(()=>++pageCount),
),
大小盒子(
宽度:10,
),
升起的按钮(
子项:文本(“-1页”),
按下时:()=>setState(()=>--pageCount),
),
],
)
],
),
),
),
容器(
子项:(
onPrev:()=>setState(()=>--currentPageIndex),
onNext:()=>setState(()=>++currentPageIndex),
currentCount:currentPageIndex,
totalCount:pageCount,
),
),
],
);
}
}
类BottomNavigation扩展了无状态小部件{
常数导航({
关键点,
@需要这个.totalCount,
@需要此.currentCount,
@需要此.onNext,
@需要此.onPrev,
}):assert(totalCount!=null),
断言(currentCount!=null),
断言(onNext!=null),
断言(onPrev!=null),
超级(键:键);
最终void函数()onPrev;
最终void函数()onNext;
最终整数总数;
最终int电流计数;
@凌驾
小部件构建(构建上下文){
返回堆栈(
儿童:[
buildHelper(),
buildIndicatorBar(),
定位(
底部:0,
左:0,,
右:0,,
孩子:排(
mainAxisAlignment:mainAxisAlignment.spaceBetween,
儿童:[
_钮扣(
'>',
onNext,
isVisible:currentCount
import 'package:flutter/material.dart';

void main() => runApp(MyApp());

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

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

class _MyHomePageState extends State<MyHomePage> {
  int currentPageIndex = 1;
  int pageCount = 8;
  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        Expanded(
          child: Center(
            child: Column(
              mainAxisSize: MainAxisSize.min,
              children: [
                Text(
                  currentPageIndex.toString(),
                ),
                Row(
                  mainAxisSize: MainAxisSize.min,
                  children: [
                    RaisedButton(
                      child: Text('+1 page'),
                      onPressed: () => setState(() => ++pageCount),
                    ),
                    SizedBox(
                      width: 10,
                    ),
                    RaisedButton(
                      child: Text('-1 page'),
                      onPressed: () => setState(() => --pageCount),
                    ),
                  ],
                )
              ],
            ),
          ),
        ),
        Container(
          child: _BottomNavigation(
            onPrev: () => setState(() => --currentPageIndex),
            onNext: () => setState(() => ++currentPageIndex),
            currentCount: currentPageIndex,
            totalCount: pageCount,
          ),
        ),
      ],
    );
  }
}

class _BottomNavigation extends StatelessWidget {
  const _BottomNavigation({
    Key key,
    @required this.totalCount,
    @required this.currentCount,
    @required this.onNext,
    @required this.onPrev,
  })  : assert(totalCount != null),
        assert(currentCount != null),
        assert(onNext != null),
        assert(onPrev != null),
        super(key: key);

  final void Function() onPrev;
  final void Function() onNext;
  final int totalCount;
  final int currentCount;

  @override
  Widget build(BuildContext context) {
    return Stack(
      children: [
        buildHelper(),
        buildIndicatorBar(),
        Positioned(
          bottom: 0,
          left: 0,
          right: 0,
          child: Row(
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
            children: [
              _button(
                '<< PREIOUS',
                onPrev,
                isVisible: currentCount > 1,
              ),
              _button(
                'NEXT >>',
                onNext,
                isVisible: currentCount < totalCount,
              ),
            ],
          ),
        ),
      ],
    );
  }

  Wrap buildHelper() {
    return Wrap(
      children: List.generate(
        totalCount,
        (index) {
          return Container(
            width: index == 0 ? 250 : 15,
            height: 20,
          );
        },
      ),
    );
  }

  Row buildIndicatorBar() {
    return Row(
      mainAxisAlignment: MainAxisAlignment.center,
      children: List.generate(totalCount, (index) {
        var isLast = totalCount != index + 1;
        var isCurrent = currentCount == index + 1;

        return Container(
          height: isCurrent ? 20 : 10,
          width: isCurrent ? 20 : 10,
          margin: EdgeInsets.only(right: isLast ? 10 : 0),
          decoration: BoxDecoration(
            shape: BoxShape.circle,
            color: isCurrent ? Colors.blueAccent : null,
            border: Border.all(
              color: Colors.blueAccent,
            ),
          ),
        );
      }),
    );
  }

  Widget _button(String text, void Function() onPress, {bool isVisible}) {
    return Visibility(
      visible: isVisible,
      child: GestureDetector(
        onTap: onPress,
        child: Text(text),
      ),
    );
  }
}