1

我在 a 中有一个PageView和一个按钮StackPageView在底部Stack)。我在bottomCenterusingStackalignment属性中有按钮。

我想定位PageView内部Stack,使其显示在按钮上方(如垂直上方,而不是上方Stack)。但是,您似乎无法使用Positioned带有 a 的小部件PageView来完成此操作。

我正在使用 a Stack,因为它PageView包含一个使用 的可缩放小部件InteractiveViewer,并且我希望在放大此小部件时按钮保持在顶部。

根据您是从头开始运行应用程序、执行 Flutter 热重启还是执行 Flutter 热重载,使用小部件包装 会产生不同的PageView错误。Positioned(但是,如果您不指定任何其他Positioned参数,即bottom,left等,则不会出现错误。)

热重载时发生的另一个问题是它确实对PageView. 它向上移动,但幅度超过bottom参数中指定的数量。它还切断了很多宽度(但不会给出任何溢出错误)。您可以在包含的第二张图片中看到这一点。

如果您指定bottom参数然后进行热重载,则会出现以下错误:

The following assertion was thrown during performResize():
Horizontal viewport was given unbounded width.

Viewports expand in the scrolling direction to fill their container. In this case, a horizontal viewport was given an unlimited amount of horizontal space in which to expand. This situation typically happens when a scrollable widget is nested inside another scrollable widget.

If this widget is always nested in a scrollable widget there is no need to use a viewport because there will always be enough horizontal space for the children. In this case, consider using a Row instead. Otherwise, consider using the "shrinkWrap" property (or a ShrinkWrappingViewport) to size the width of the viewport to the sum of the widths of its children.

如果您指定bottom参数,然后从头开始停止并运行应用程序或进行热重启,则会出现以下错误:

错误一:

The following NoSuchMethodError was thrown during performLayout():
The method 'toStringAsFixed' was called on null.
Receiver: null
Tried calling: toStringAsFixed(1)

错误 2(此错误的几种变体):

RenderBox was not laid out: RenderPointerListener#99b5a relayoutBoundary=up8 NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
'package:flutter/src/rendering/box.dart':
Failed assertion: line 1785 pos 12: 'hasSize'

这是一个显示我的问题的简单应用程序:

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) => MaterialApp(home: MyHomePage());
}

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

class _MyHomePageState extends State<MyHomePage> {
  PageController _pageController = PageController(initialPage: 0);
  int currentIndex = 0;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: Column(
          children: [
            TopToolbar(currentIndex == 0
                ? 'Car'
                : currentIndex == 1
                    ? 'Bike'
                    : 'Walk'),
            Expanded(
              child: Stack(
                alignment: AlignmentDirectional.bottomCenter,
                children: [
                  Positioned(
// vvvvvvvvvvvvvvvv Specifying this causes the errors: vvvvvvvvvvvvvvvvvvvvvvvv
                    bottom: 50, // 50 because that is the height of the button
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
                    child: PageView(
                      controller: _pageController,
                      onPageChanged: (page) {
                        setState(() {
                          currentIndex = page;
                        });
                      },
                      children: [
                        CarScreen(),
                        BikeScreen(),
                        WalkScreen(),
                      ],
                    ),
                  ),
                  Container(
                      height: 50, // <-------------------- Height of the button
                      color: Colors.lightBlueAccent,
                      child: Text('A button', style: TextStyle(fontSize: 20)))
                ],
              ),
            ),
          ],
        ),
      ),
// ==== I don't think the code below is relevant to the question, but who knows:
      bottomNavigationBar: BottomNavigationBar(
        currentIndex: currentIndex,
        onTap: (value) {
          setState(() {
            currentIndex = value;
            _pageController.jumpToPage(value);
          });
        },
        items: [
          BottomNavigationBarItem(
              icon: Icon(Icons.directions_car), label: 'Car'),
          BottomNavigationBarItem(
              icon: Icon(Icons.directions_bike), label: 'Bike'),
          BottomNavigationBarItem(
              icon: Icon(Icons.directions_walk), label: 'Walk'),
        ],
      ),
    );
  }
}

class TopToolbar extends StatelessWidget {
  final String label;
  TopToolbar(this.label);

  @override
  Widget build(BuildContext context) => Container(
        color: Colors.lightBlueAccent,
        child: Row(
          children: [
            Text('Custom toolbar for $label', style: TextStyle(fontSize: 20)),
          ],
        ),
      );
}

class CarScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) => ScreenWidget('Car');
}

class BikeScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) => ScreenWidget('Bike');
}

class WalkScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) => ScreenWidget('Walk');
}

class ScreenWidget extends StatelessWidget {
  final String title;
  ScreenWidget(this.title);
  @override
  Widget build(BuildContext context) => Center(
      child: Container(
          width: 200,
          height: 550,
          alignment: Alignment.center,
          color: Colors.grey,
          child: Text('$title Screen', style: TextStyle(fontSize: 20))));
}


bottom没有指定参数的样子。看到按钮覆盖了部分PageView,我不希望发生这种情况,这就是我要解决的问题:

底部未指定

bottom指定参数然后进行热重载时的样子。您可以看到它向上移动的幅度超过了 指定的bottom幅度,并且它切断了很多宽度而不会出现溢出错误:

底部指定然后热重载

bottom当您指定参数然后热启动或停止并从头开始运行应用程序时的样子。和PageView按钮不见了:

底部指定然后热重启或停止并从头开始运行

4

0 回答 0