视口大于 maxwidth 时 SingleChildScrollView 渲染溢出
Posted
技术标签:
【中文标题】视口大于 maxwidth 时 SingleChildScrollView 渲染溢出【英文标题】:SingleChildScrollView rendering overflow when viewport greater than maxwidth 【发布时间】:2022-01-01 12:15:04 【问题描述】:我正在尝试将网络内容设置为具有最大宽度(图像中的橙色),并始终填充可用高度,我已经达到了。
但是当窗口宽于最大内容宽度,并且窗口高度小于内容、页眉和页脚组合的高度时。我得到一个渲染溢出。 当我追求的是内容保持其高度和启用滚动时。
注意:如果每个文本只有 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')),
),
],
),
),
),
);
,
),
);
【问题讨论】:
【参考方案1】:在将其更改为使用只有 2 个子项的 Column 并将对齐设置为 SpaceBetween
时,当您将窗口宽度设置为比内容短时溢出问题就会消失。
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'))),
],
),
),
);
,
),
);
【讨论】:
【参考方案2】:如果页眉和页脚高度各为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')),
),
],
),
),
),
);
,
),
);
【讨论】:
您好 Meysam,感谢您的反馈。我正在尝试实现的设计没有粘性页眉或页脚,并且需要成为将滚动的整个页面的一部分。 @OneGoodRun 嗨,由于您希望页眉和页脚滚动,所以您必须从页眉和页脚的高度减少中间高度。我编辑了答案。 嗨 Meysam,嗯,我仍然需要保持内容的可见性。这似乎会使 Expanded 中的内容随着屏幕变短而不是激活滚动而消失。 我测试了你的代码。它工作正常。可能是由于 Chrome 浏览器溢出以上是关于视口大于 maxwidth 时 SingleChildScrollView 渲染溢出的主要内容,如果未能解决你的问题,请参考以下文章