我在 a 中有一个PageView
和一个按钮Stack
(PageView
在底部Stack
)。我在bottomCenter
usingStack
的alignment
属性中有按钮。
我想定位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
按钮不见了: