(Flutter)将水平列表视图对齐到屏幕底部(及相关问题)

12 浏览
0 Comments

(Flutter)将水平列表视图对齐到屏幕底部(及相关问题)

我的应用程序需要一个水平的ListView,可以点击其中的项。\n布局描述如下\nContainer\n|_ Stack\n |_ (背景内容)\n |_ Column (覆盖层,垂直底部对齐)\n |_ Expand (填充上方空间)\n |_ ListView (水平)\n |_ SizedBox (填充)\n\n问题\n当插入这个ListView(或取消注释)时,Flutter会抛出以下错误:\n======== Exception caught by rendering library =====================================================\nThe following assertion was thrown during performLayout():\n\'package:flutter/src/rendering/viewport.dart\': Failed assertion: line 1852 pos 16: \'constraints.hasBoundedHeight\': is not true.\nEither the assertion indicates an error in the framework itself, or we should provide substantially more information in this error message to help you determine and fix the underlying cause.\nIn either case, please report this assertion by filing a bug on GitHub:\n https://github.com/flutter/flutter/issues/new?template=BUG.md\nThe relevant error-causing widget was: \n ListView file:///C:/Users/CybeX/CozyUp/cozyup-mobile-flutter/lib/ui/components/ui_component_partner_selector.dart:76:13\nWhen the exception was thrown, this was the stack: \n#2 RenderShrinkWrappingViewport.performLayout (package:flutter/src/rendering/viewport.dart:1852:16)\n#3 RenderObject.layout (package:flutter/src/rendering/object.dart:1777:7)\n#4 RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:113:14)\n#5 RenderObject.layout (package:flutter/src/rendering/object.dart:1777:7)\n#6 RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:113:14)\n...\nThe following RenderObject was being processed when the exception was fired: RenderShrinkWrappingViewport#400d9 relayoutBoundary=up16 NEEDS-LAYOUT NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE\n... needs compositing\n... parentData: (can use size)\n... constraints: BoxConstraints(0.0<=w<=395.4, 0.0<=h<=Infinity)\n... size: MISSING\n... axisDirection: right\n... crossAxisDirection: down\n... offset: ScrollPositionWithSingleContext#72596(offset: 0.0, range: null..null, viewport: null, ScrollableState, ClampingScrollPhysics -> RangeMaintainingScrollPhysics, IdleScrollActivity#601d0, ScrollDirection.idle)\nRenderObject: RenderShrinkWrappingViewport#400d9 relayoutBoundary=up16 NEEDS-LAYOUT NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE\n\n我尝试将ListView包装在Expanded中,但这会使其居中显示在屏幕中间,如这里所建议的。我尝试在顶部添加一个Expanded,如这里所建议的,但Flutter不喜欢这样做。\n顺便说一下,我还尝试了ShrinkWrap(对此并没有太多期望-也没有帮助)。\nMVCE\nimport \'package:flutter/material.dart\';\nvoid main() async {\n runApp(MaterialApp(home: MyApp()));\n}\nclass MyApp extends StatelessWidget {\n // This widget is the root of your application.\n @override\n Widget build(BuildContext context) {\n List imgSrc = [\n \"https://randomuser.me/api/portraits/women/84.jpg\",\n \"https://randomuser.me/api/portraits/men/82.jpg\",\n \"https://randomuser.me/api/portraits/women/11.jpg\",\n \"https://randomuser.me/api/portraits/women/61.jpg\",\n \"https://randomuser.me/api/portraits/men/1.jpg\",\n ];\n List _listviewItems() {\n return imgSrc\n .map((e) => Image.network(e))\n .map((e) => Image(\n image: e.image,\n fit: BoxFit.scaleDown,\n width: 64,\n ))\n .toList();\n }\n Widget w = Container(\n child: Stack(\n children: [\n // Center(\n // child: cards.first,\n // ),\n Column(\n mainAxisAlignment: MainAxisAlignment.end,\n children: [\n Expanded(\n child: ListView(\n padding: const EdgeInsets.all(0.0),\n scrollDirection: Axis.horizontal,\n children: _listviewItems(),\n )),\n SizedBox(\n height: 8,\n )\n ],\n )\n ],\n ));\n return Scaffold(\n body: Container(width: double.infinity, child: w),\n );\n }\n}\n\n\"enter\n上图是使用Expanded包装的ListView,即\n Column(\n mainAxisAlignment: MainAxisAlignment.end,\n children: [\n Expanded(\n child: Container()\n ),\n ListView(\n padding: const EdgeInsets.all(0.0),\n scrollDirection: Axis.horizontal,\n children: _listviewItems(),\n ),\n SizedBox(\n height: 8,\n )\n ],\n )\n\n问题:\n我如何将水平的listview对齐到屏幕底部,允许水平滚动(如上图所示)?\n顺便说一下,我添加了shrinkWrap: true,并将Column(在Stack内部)包装在Expanded中,结果出现了一个错误,导致我到这里,这里建议相反的做法-非常令人沮丧!

0
0 Comments

在这个问题中,出现的原因是想要将水平的ListView对齐到屏幕底部,但是没有找到合适的方法。而解决方法有两种。

第一种解决方法是使用bottomSheet。具体的代码实现如下:

return Scaffold(

appBar: ...,

body: ...,

bottomSheet: SizedBox(height: 64, child: listview()),

);

第二种解决方法是将ListView包裹在Align和SizedBox中。具体的代码实现如下:

Expanded(

child: Align(

alignment: Alignment.bottomCenter,

child: SizedBox(

height: 64,

child: ListView(

padding: const EdgeInsets.all(0.0),

scrollDirection: Axis.horizontal,

children: _listviewItems(),

),

),

),

)

这两种解决方法都可以将水平的ListView对齐到屏幕底部。

以下是解决方法1的完整代码:

import 'package:flutter/material.dart';

void main() async {

runApp(MaterialApp(home: MyApp()));

}

class MyApp extends StatelessWidget {

Widget build(BuildContext context) {

List imgSrc = [

"https://randomuser.me/api/portraits/women/84.jpg",

"https://randomuser.me/api/portraits/men/82.jpg",

"https://randomuser.me/api/portraits/women/11.jpg",

"https://randomuser.me/api/portraits/women/61.jpg",

"https://randomuser.me/api/portraits/men/1.jpg",

"https://randomuser.me/api/portraits/men/2.jpg",

"https://randomuser.me/api/portraits/men/3.jpg",

"https://randomuser.me/api/portraits/men/4.jpg",

"https://randomuser.me/api/portraits/men/5.jpg",

"https://randomuser.me/api/portraits/men/6.jpg",

"https://randomuser.me/api/portraits/men/7.jpg",

];

Widget listview() {

List imgList = imgSrc

.map((e) => Image.network(e))

.map((e) => Image(

image: e.image,

fit: BoxFit.scaleDown,

width: 64,

))

.toList();

return ListView(

scrollDirection: Axis.horizontal,

children: imgList,

);

}

return Scaffold(

appBar: AppBar(title: const Text('AppBar Demo')),

body: Center(

child: Container(

child: Text("other content"),

),

),

bottomSheet: SizedBox(height: 64, child: listview()),

);

}

}

以下是解决方法2的完整代码:

import 'package:flutter/material.dart';

void main() async {

runApp(MaterialApp(home: MyApp()));

}

class MyApp extends StatelessWidget {

Widget build(BuildContext context) {

List imgSrc = [

"https://randomuser.me/api/portraits/women/84.jpg",

"https://randomuser.me/api/portraits/men/82.jpg",

"https://randomuser.me/api/portraits/women/11.jpg",

"https://randomuser.me/api/portraits/women/61.jpg",

"https://randomuser.me/api/portraits/men/1.jpg",

"https://randomuser.me/api/portraits/men/2.jpg",

"https://randomuser.me/api/portraits/men/3.jpg",

"https://randomuser.me/api/portraits/men/4.jpg",

"https://randomuser.me/api/portraits/men/5.jpg",

"https://randomuser.me/api/portraits/men/6.jpg",

"https://randomuser.me/api/portraits/men/7.jpg",

];

List _listviewItems() {

return imgSrc

.map((e) => Image.network(e))

.map((e) => Image(

image: e.image,

fit: BoxFit.scaleDown,

width: 64,

))

.toList();

}

Widget w = Container(

child: Stack(

children: [

Column(

mainAxisAlignment: MainAxisAlignment.end,

children: [

Expanded(

child: Align(

alignment: Alignment.bottomCenter,

child: SizedBox(

height: 64,

child: ListView(

padding: const EdgeInsets.all(0.0),

scrollDirection: Axis.horizontal,

children: _listviewItems(),

),

),

),

),

SizedBox(

height: 8,

)

],

)

],

),

);

return Scaffold(

body: Container(width: double.infinity, child: w),

);

}

}

0
0 Comments

问题出现的原因是希望将水平的ListView对齐在屏幕底部,但是没有找到其他合适的方法来实现这个效果。解决方法是将ListView包裹在一个Container中,并给Container一个固定的高度。以下是解决方法的示例代码:

Container(

height: 50,

ListView(

padding: const EdgeInsets.all(0.0),

scrollDirection: Axis.horizontal,

children: _listviewItems(),

),

),

作者在解决问题时避免使用静态尺寸,但没有找到其他适合的选项,所以采用了这种方法。

0