当视口大于最大宽度时,SingleChildScrollView 渲染溢出
SingleChildScrollView rendering overflow when viewport greater than maxwidth
我正在尝试将 Web 内容设置为具有最大宽度(图像中的橙色),并始终填充可用高度,我已经做到了。
然而,当 window 比最大内容宽度更宽,并且 window 高度小于内容、页眉和页脚的总和高度时。我遇到了渲染溢出。
当我所追求的是内容保持其高度并启用滚动时。
注意:如果每个文本只有 1 行,问题似乎就解决了。
我试过使用 CustomeScrollView 和 SliverFillRemaining,但我遇到了同样的问题。
如有任何帮助,我们将不胜感激。
import 'package:flutter/material.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return const MaterialApp(
title: 'Scrollable Layout',
home: ScrollableLayout(),
);
}
}
class ContentWidthContainer extends StatelessWidget {
final Widget child;
const ContentWidthContainer({Key? key, required this.child})
: super(key: key);
@override
Widget build(BuildContext context) {
return Container(
color: Colors.grey,
child: Align(
alignment: Alignment.topCenter,
child: Container(
color: Colors.orange,
width: double.infinity,
constraints: const BoxConstraints(
maxWidth: 960,
),
padding: const EdgeInsets.symmetric(horizontal: 75),
child: child),
),
);
}
}
class ScrollableLayout extends StatelessWidget {
const ScrollableLayout({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return DefaultTextStyle(
style: Theme.of(context).textTheme.bodyText2!,
child: LayoutBuilder(
builder: (BuildContext context, BoxConstraints viewportConstraints) {
return SingleChildScrollView(
child: ConstrainedBox(
constraints: BoxConstraints(
minHeight: viewportConstraints.maxHeight,
),
child: IntrinsicHeight(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
ContentWidthContainer(
child: Container(
color: Colors.indigo,
height: 200,
child: const Text('Header: Fixed Height')),
),
Expanded(
child: ContentWidthContainer(
child: Container(
color: Colors.white,
child: Column(
children: const [
Text(
'ContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContent'),
Text('Content'),
Text('Content'),
Text('Content'),
Text('Content'),
Text('Content'),
Text('Content'),
],
)),
),
),
ContentWidthContainer(
child: Container(
color: Colors.indigo,
height: 200,
child: const Text('Footer: Fixed Height')),
),
],
),
),
),
);
},
),
);
}
}
如果页眉和页脚的高度都是200,那么中间内容的高度应该小于400。
height: MediaQuery.of(context).size.height - 400
因此将您的代码更改为
@override
Widget build(BuildContext context) {
return DefaultTextStyle(
style: Theme.of(context).textTheme.bodyText2!,
child: LayoutBuilder(
builder: (BuildContext context, BoxConstraints viewportConstraints)
{
return SingleChildScrollView(
child: ConstrainedBox(
constraints: BoxConstraints(
minHeight: viewportConstraints.maxHeight,
),
child: IntrinsicHeight(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
ContentWidthContainer(
child: Container(
color: Colors.indigo,
height: 200,
child: const Text('Header: Fixed Height')),
),
Expanded(
child: ContentWidthContainer(
child: Container(
height: MediaQuery.of(context).size.height - 400,
color: Colors.white,
child: Column(
children: const [
Text(
'ContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContent'),
Text('Content'),
Text('Content'),
Text('Content'),
Text('Content'),
Text('Content'),
Text('Content'),
],
)),
),
),
ContentWidthContainer(
child: Container(
color: Colors.indigo,
height: 200,
child: const Text('Footer: Fixed Height')),
),
],
),
),
),
);
},
),
);
}
将其更改为使用一个只有 2 个子项且对齐方式设置为 SpaceBetween
的列后,当您将宽度设置为 window 但比内容短时,溢出问题就会消失。
class ScrollableSpaceBetweenLayout extends StatelessWidget {
const ScrollableSpaceBetweenLayout({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return DefaultTextStyle(
style: Theme.of(context).textTheme.bodyText2!,
child: LayoutBuilder(
builder: (BuildContext context, BoxConstraints viewportConstraints) {
return SingleChildScrollView(
child: Container(
color: Colors.black12, // the background / sides
constraints: BoxConstraints(
minHeight: viewportConstraints.maxHeight,
),
child: Column(
mainAxisSize: MainAxisSize.max,
children: <Widget>[
Container(
color: Colors.indigo,
height: 200,
child: const Align(
alignment: Alignment.center,
child: Text('Header: Fixed Height'))),
Container(
color: Colors.orange,
constraints: BoxConstraints(
maxWidth: 960,
minHeight: max(viewportConstraints.maxHeight - 400, 0),
),
padding: const EdgeInsets.symmetric(horizontal: 75),
child: Container(
color: Colors.white,
child: Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Column(
children: const [
Text(
'ContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContent'),
Text('Content'),
Text('Content'),
Text('Content'),
Text('Content'),
Text('Content'),
Text('Content'),
],
),
Container(
child: const Text('spacer'),
height: 1,
color: Colors.red)
],
)),
),
Container(
color: Colors.indigo,
height: 200,
child: const Align(
alignment: Alignment.center,
child: Text('Footer: Fixed Height'))),
],
),
),
);
},
),
);
}
}
我正在尝试将 Web 内容设置为具有最大宽度(图像中的橙色),并始终填充可用高度,我已经做到了。
然而,当 window 比最大内容宽度更宽,并且 window 高度小于内容、页眉和页脚的总和高度时。我遇到了渲染溢出。 当我所追求的是内容保持其高度并启用滚动时。
注意:如果每个文本只有 1 行,问题似乎就解决了。
我试过使用 CustomeScrollView 和 SliverFillRemaining,但我遇到了同样的问题。
如有任何帮助,我们将不胜感激。
import 'package:flutter/material.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return const MaterialApp(
title: 'Scrollable Layout',
home: ScrollableLayout(),
);
}
}
class ContentWidthContainer extends StatelessWidget {
final Widget child;
const ContentWidthContainer({Key? key, required this.child})
: super(key: key);
@override
Widget build(BuildContext context) {
return Container(
color: Colors.grey,
child: Align(
alignment: Alignment.topCenter,
child: Container(
color: Colors.orange,
width: double.infinity,
constraints: const BoxConstraints(
maxWidth: 960,
),
padding: const EdgeInsets.symmetric(horizontal: 75),
child: child),
),
);
}
}
class ScrollableLayout extends StatelessWidget {
const ScrollableLayout({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return DefaultTextStyle(
style: Theme.of(context).textTheme.bodyText2!,
child: LayoutBuilder(
builder: (BuildContext context, BoxConstraints viewportConstraints) {
return SingleChildScrollView(
child: ConstrainedBox(
constraints: BoxConstraints(
minHeight: viewportConstraints.maxHeight,
),
child: IntrinsicHeight(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
ContentWidthContainer(
child: Container(
color: Colors.indigo,
height: 200,
child: const Text('Header: Fixed Height')),
),
Expanded(
child: ContentWidthContainer(
child: Container(
color: Colors.white,
child: Column(
children: const [
Text(
'ContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContent'),
Text('Content'),
Text('Content'),
Text('Content'),
Text('Content'),
Text('Content'),
Text('Content'),
],
)),
),
),
ContentWidthContainer(
child: Container(
color: Colors.indigo,
height: 200,
child: const Text('Footer: Fixed Height')),
),
],
),
),
),
);
},
),
);
}
}
如果页眉和页脚的高度都是200,那么中间内容的高度应该小于400。
height: MediaQuery.of(context).size.height - 400
因此将您的代码更改为
@override
Widget build(BuildContext context) {
return DefaultTextStyle(
style: Theme.of(context).textTheme.bodyText2!,
child: LayoutBuilder(
builder: (BuildContext context, BoxConstraints viewportConstraints)
{
return SingleChildScrollView(
child: ConstrainedBox(
constraints: BoxConstraints(
minHeight: viewportConstraints.maxHeight,
),
child: IntrinsicHeight(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
ContentWidthContainer(
child: Container(
color: Colors.indigo,
height: 200,
child: const Text('Header: Fixed Height')),
),
Expanded(
child: ContentWidthContainer(
child: Container(
height: MediaQuery.of(context).size.height - 400,
color: Colors.white,
child: Column(
children: const [
Text(
'ContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContent'),
Text('Content'),
Text('Content'),
Text('Content'),
Text('Content'),
Text('Content'),
Text('Content'),
],
)),
),
),
ContentWidthContainer(
child: Container(
color: Colors.indigo,
height: 200,
child: const Text('Footer: Fixed Height')),
),
],
),
),
),
);
},
),
);
}
将其更改为使用一个只有 2 个子项且对齐方式设置为 SpaceBetween
的列后,当您将宽度设置为 window 但比内容短时,溢出问题就会消失。
class ScrollableSpaceBetweenLayout extends StatelessWidget {
const ScrollableSpaceBetweenLayout({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return DefaultTextStyle(
style: Theme.of(context).textTheme.bodyText2!,
child: LayoutBuilder(
builder: (BuildContext context, BoxConstraints viewportConstraints) {
return SingleChildScrollView(
child: Container(
color: Colors.black12, // the background / sides
constraints: BoxConstraints(
minHeight: viewportConstraints.maxHeight,
),
child: Column(
mainAxisSize: MainAxisSize.max,
children: <Widget>[
Container(
color: Colors.indigo,
height: 200,
child: const Align(
alignment: Alignment.center,
child: Text('Header: Fixed Height'))),
Container(
color: Colors.orange,
constraints: BoxConstraints(
maxWidth: 960,
minHeight: max(viewportConstraints.maxHeight - 400, 0),
),
padding: const EdgeInsets.symmetric(horizontal: 75),
child: Container(
color: Colors.white,
child: Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Column(
children: const [
Text(
'ContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContent'),
Text('Content'),
Text('Content'),
Text('Content'),
Text('Content'),
Text('Content'),
Text('Content'),
],
),
Container(
child: const Text('spacer'),
height: 1,
color: Colors.red)
],
)),
),
Container(
color: Colors.indigo,
height: 200,
child: const Align(
alignment: Alignment.center,
child: Text('Footer: Fixed Height'))),
],
),
),
);
},
),
);
}
}