0

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

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

当前小部件

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

所需的小部件

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

将所有内容放在 a 中很容易Wrap,但这会使NEXT-button 换行而不是页面指示器,因为这是最后一个元素。

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

4

1 回答 1

0

最简单的解决方案是添加隐形包裹来计算高度。

在此处输入图像描述

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),
      ),
    );
  }
}
于 2020-09-14T15:37:08.013 回答