Flutter - 使用 Column/Expanded/ListView 的布局问题
Posted
技术标签:
【中文标题】Flutter - 使用 Column/Expanded/ListView 的布局问题【英文标题】:Flutter - Layout problem using Column/Expanded/ListView 【发布时间】:2020-12-18 11:34:25 【问题描述】:我对 Flutter 很陌生,我似乎无法解决这个问题。
我想显示我的自定义卡片式 Ink 容器的 ListView 并且几乎实现了它。但是,当我向下滚动时,ListView 会延伸到我的 Text 小部件(列中的前一项)后面:
Expanded widget behind text widget
滚动时查看“图库”文本的后面: Animated GIF showing undesired behavior
我希望我的 ListView 小部件滚动,而容器不显示在“图库”文本后面。
我尝试不使用 Expanded 小部件(ListView.builder() 直接在 Column 子项下),但我在调试控制台中收到此错误消息:
════════ 渲染库捕获的异常 ═════════════════════════════════ RenderBox 没有布局: RenderRepaintBoundary#8dc77 relayoutBoundary=up8 NEEDS-PAINT 'package:flutter/src/rendering/box.dart':断言失败:第 1702 行 pos 12: 'hasSize' 相关的导致错误的小部件是 专栏
而且列表根本不显示。
这是我的代码:
class Gallery extends StatelessWidget
final List<_ChallengeCard> challengestest = [
_ChallengeCard(title: 'Challenge #1', subtitle: 'Completed on 13/11/1978'),
_ChallengeCard(title: 'Challenge #2', subtitle: 'Completed on 12/18/2043'),
_ChallengeCard(title: 'Challenge #3', subtitle: 'Current challenge'),
_ChallengeCard(title: 'Challenge #4', subtitle: 'Locked'),
_ChallengeCard(title: 'Challenge #5', subtitle: 'Locked'),
_ChallengeCard(title: 'Challenge #6', subtitle: 'Locked'),
_ChallengeCard(title: 'Challenge #7', subtitle: 'Locked'),
];
Widget build(BuildContext context)
return Scaffold(
body: Column(
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.max,
children: [
Text(
'Gallery',
style: GoogleFonts.alexBrush(fontSize: 55),
textAlign: TextAlign.center,
),
Expanded(
child: ListView.builder(
itemCount: challengestest.length,
itemBuilder: (context, index)
return Container(
padding: EdgeInsets.symmetric(vertical: 8.0),
child: InkWell(
onTap: (),
child: challengestest[index]
),
);
,
),
),
],
),
);
还有一些额外的类,以便您可以看到 ListView 项目的具体内容(但我怀疑它们与问题有关):
class _ChallengeCard extends StatelessWidget
_ChallengeCard(
Key key,
this.title,
this.subtitle,
) : super(key: key);
final String title;
final String subtitle;
@override
Widget build(BuildContext context)
return Ink(
padding: EdgeInsets.all(11.0),
decoration: BoxDecoration(
color: Color(0xFF11001A),
borderRadius: BorderRadius.all(Radius.circular(10.0))),
child: Container(
alignment: Alignment.topLeft,
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsets.symmetric(horizontal: 8.0),
child: Icon(Icons.star,color: Colors.white, size: 40.0,),
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children:<Widget>[
Text(
'$title',
style: GoogleFonts.lora(fontSize: 25),
),
Text(
'$subtitle',
style: GoogleFonts.lora(fontSize: 15),
),
],
),
],
),
),
);
“gallery”类是从 main.dart 文件中调用的(这就是为什么整个应用程序中有一个底部导航栏的原因),但我没有包含它,因为它与问题无关。
提前致谢!
【问题讨论】:
目前尚不清楚您所描述的不良行为来自图像,并且您提供的代码不会显示显示的小部件的想法使情况更加复杂。如果您提供了一个 gif 而不是显示不良行为的静态图像,或许可以? @Abion47 我添加了一个 GIF 来显示不受欢迎的行为以及更多代码。谢谢! 【参考方案1】:您也可以通过将小部件包装在单个子滚动视图中来使文本滚动
...
SingleChildScrollView(// add a scrollview
child:
Column(
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.max,
children: [
Text(
'Gallery',
style: GoogleFonts.alexBrush(fontSize: 55),
textAlign: TextAlign.center,
),
//remove the expanded widget
ListView.builder(
shrinkWrap: true, // make shrikwrap true
physics: NeverScrollableScrollPhysics(), // add this physics so it won't scroll
itemCount: challengestest.length,
itemBuilder: (context, index)
return Container(
... // rest of your code here
);
),
]))
【讨论】:
感谢您的回复!这确实可以很好地使文本与卡片一起滚动,但我希望保持文本像现在一样静态。我只是不希望这些框在向上滚动时出现在文本后面(如 GIF 中所示)。【参考方案2】:我终于通过使用 AppBar 小部件而不是“图库”标题的 Text 小部件来让它工作。
Scaffold 不再包含 Column 小部件,仅包含 ListView.Builder:
Widget build(BuildContext context)
return Scaffold(
body: ListView.builder(
shrinkWrap: true,
itemCount: challengestest.length,
itemBuilder: (context, index)
return Container(
padding: EdgeInsets.symmetric(vertical: 8.0),
child: InkWell(
onTap: (),
child: challengestest[index]
),
);
,
),
);
文本“Gallery”已被移动为经过大量修改的 AppBar,带有 Stack 小部件以保留其外观:
Stack(
children: <Widget>[
Image.asset(
"assets/images/bgpurple.jpeg",
height: MediaQuery.of(context).size.height,
width: MediaQuery.of(context).size.width,
fit: BoxFit.cover,
),
Scaffold(
appBar: PreferredSize(
preferredSize: Size.fromHeight(85.0),
child: AppBar(
automaticallyImplyLeading: false,
elevation: 0.0,
backgroundColor: Colors.transparent,
centerTitle: true,
flexibleSpace: Padding(
padding: const EdgeInsets.only(top: 60.0),
child: Center(
child: Text(
_myPageTitles[_selectedIndex],
style: GoogleFonts.alexBrush(
fontSize: 45,
color: Colors.white,
)
),
),
),
),
),
【讨论】:
以上是关于Flutter - 使用 Column/Expanded/ListView 的布局问题的主要内容,如果未能解决你的问题,请参考以下文章
Flutter - 使用 google_sign_in 库时未找到 <Flutter/Flutter.h>
Flutter——如何使用 html 链接渲染 Flutter 文本 [重复]
flutter系列之:在flutter中使用导航Navigator
Flutter - 无法在flutter web中使用动态链接