Как создать вид прокрутки с фиксированным нижним колонтитулом с помощью Flutter? - PullRequest
0 голосов
/ 03 января 2019

Я хотел бы создать представление, которое должно иметь Column с представлением прокрутки (например, что-то вроде SingleChildScrollView) и нижний колонтитул независимо от размера экрана. Если экран достаточно велик, он будет использовать пустое пространство между прокруткой и нижним колонтитулом, если нет, он будет расширяться и сделает виджет только над прокруткой нижнего колонтитула.

Это более или менее похоже на Listview с прокруткой нижнего колонтитула внизу , но с той разницей, что я хочу, чтобы клавиатура переполняла нижний колонтитул, и она также должна оставаться на месте.

Что-то вроде

example

return Scaffold(
      body: Column(
        mainAxisAlignment: MainAxisAlignment.spaceBetween,
        children: <Widget>[
          SingleChildScrollView(
            child: Padding(
              padding: const EdgeInsets.only(left: 30.0, right: 30.0, top: 80.0),
              child: Form(
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.stretch,
                  children: <Widget>[
                   // Multiple widgets and form fields
                  ],
                ),
              ),
            ),
          ),
          Padding(
            padding: const EdgeInsets.only(top: 50.0),
            child: SafeArea(
              child: Row(
                mainAxisAlignment: MainAxisAlignment.spaceBetween,
                children: <Widget>[
                  // Footer widgets
                ],
              ),
            ),
          )
        ],
      ),
    );

Ответы [ 2 ]

0 голосов
/ 27 июля 2019

Несмотря на то, что ответ Реми был правильным, я действительно нашел более простой способ достичь того, что искал, просто комбинируя LayoutBuilder с Intrinsic Height.

class ScrollableFooter extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return LayoutBuilder(
        builder: (BuildContext context, BoxConstraints constraints) {
      return SingleChildScrollView(
        child: ConstrainedBox(
          constraints: constraints.copyWith(
            minHeight: constraints.maxHeight,
            maxHeight: double.infinity,
          ),
          child: IntrinsicHeight(
            child: Column(
              children: <Widget>[
               // Your body widgets here
                Expanded(
                  child: Align(
                    alignment: Alignment.bottomCenter,
                    child: // Your footer widget
                  ),
                ),
              ],
            ),
          ),
        ),
      );
    });
  }
}
0 голосов
/ 03 января 2019

Сложность в том, что Column и SingleChildScrollView трудно работать вместе, потому что одному нужны ограничения, а другому их снимают.

Хитрость в том, чтобы использовать CustomMultiChildLayout и выполнять вычисления самостоятельно.,MediaQuery помогает получить размер клавиатуры, чтобы нижний колонтитул мог исчезнуть, оставляя больше места для содержимого.

Вот виджет многократного использования, который сделает это за вас:

class FooterLayout extends StatelessWidget {
  const FooterLayout({
    Key key,
    @required this.body,
    @required this.footer,
  }) : super(key: key);

  final Container body;
  final Container footer;

  @override
  Widget build(BuildContext context) {
    return CustomMultiChildLayout(
      delegate: _FooterLayoutDelegate(MediaQuery.of(context).viewInsets),
      children: <Widget>[
        LayoutId(
          id: _FooterLayout.body,
          child: body,
        ),
        LayoutId(
          id: _FooterLayout.footer,
          child: footer,
        ),
      ],
    );
  }
}

enum _FooterLayout {
  footer,
  body,
}

class _FooterLayoutDelegate extends MultiChildLayoutDelegate {
  final EdgeInsets viewInsets;

  _FooterLayoutDelegate(this.viewInsets);

  @override
  void performLayout(Size size) {
    size = Size(size.width, size.height + viewInsets.bottom);
    final footer =
        layoutChild(_FooterLayout.footer, BoxConstraints.loose(size));

    final bodyConstraints = BoxConstraints.tightFor(
      height: size.height - max(footer.height, viewInsets.bottom),
      width: size.width,
    );

    final body = layoutChild(_FooterLayout.body, bodyConstraints);

    positionChild(_FooterLayout.body, Offset.zero);
    positionChild(_FooterLayout.footer, Offset(0, body.height));
  }

  @override
  bool shouldRelayout(MultiChildLayoutDelegate oldDelegate) {
    return true;
  }
}

Используется как таковой:

FooterLayout(
  body: body,
  footer: footer,
),
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...