我想建立一个类似instagram的个人资料页面,其中当前用户的所有帖子都列在Feed中。在此之上,应该显示有关用户的一些信息(头像,关注者数量,帖子数量,个人简介等)。 用户应该可以滚动整个页面。此刻,页面只能滚动到ListView.builder中sizeBox窗口小部件的高度。就是这样:
ProfilePage 类的构建方法如下:
CREATE TABLE "Table1"
(
"D_ID" NUMBER(4,0),
"D_N" VARCHAR2(30) COLLATE "USING_NLS_COMP" CONSTRAINT "D_N_NN" NOT NULL ENABLE,
"TEMPDEPTID" VARCHAR2(4) COLLATE "USING_NLS_COMP",
CONSTRAINT "D_ID_PK" PRIMARY KEY ("D_ID")
USING INDEX ENABLE
) DEFAULT COLLATION "USING_NLS_COMP"
/
ALTER TABLE "Table1" ADD CONSTRAINT "D_L_FK" FOREIGN KEY ("L_ID")
REFERENCES "Table3" ("L_ID") ENABLE
/
ALTER TABLE "Table1" ADD CONSTRAINT "D_M_FK" FOREIGN KEY ("M_ID")
REFERENCES "Table2" ("E_ID") ENABLE
/
CREATE TABLE "Table2"
(
"D_ID" NUMBER(4,0),
"TEMPDEPTID" VARCHAR2(4) COLLATE "USING_NLS_COMP",
"D_N" VARCHAR2(30) COLLATE "USING_NLS_COMP",
CONSTRAINT "EMP_EMP_ID_PK" PRIMARY KEY ("E_ID")
USING INDEX ENABLE,
) DEFAULT COLLATION "USING_NLS_COMP"
/
ALTER TABLE "Table2" ADD CONSTRAINT "EMP_D_FK" FOREIGN KEY ("D_ID")
REFERENCES "Table1" ("D_ID") ENABLE
/
ALTER TABLE "Table2" ADD CONSTRAINT "EMP_M_FK" FOREIGN KEY ("M_ID")
REFERENCES "Table2" ("E_ID") ENABLE
/
在 postImagesWidget 中,我正在使用ListView.builder构建提要:
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
appBar: AppBar(),
body: ListView(
children: <Widget>[
Padding(
padding: const EdgeInsets.only(left: 25.0, top: 30.0),
child: Text(_user.displayName,
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
fontSize: 20.0)),
),
...(all the other information for the "header-part")
postImagesWidget(),
])));}
我必须添加一个sizeBox-Widget以避免此错误:
引发了另一个异常:未布置RenderBox:RenderViewport#50ccf NEEDS-PAINT
此错误的描述说,我应该将收缩包装添加到ListView.builder中,但是在滚动了此错误之后,这会使我的整个应用程序崩溃:
断言失败:470行pos 12:'child.hasSize':不正确。
我如何使整个页面可滚动而不是将两个部分(页眉和提要)分别滚动?
我知道我与事实有关,我在ListView中使用ListView.builder ...
最好的问候。
答案 0 :(得分:1)
仅当您希望布局的一部分在特定区域内可滚动时,我才不会在列表中使用大小可变的组件。
但是,在您的情况下,我看到您希望整个页面都是可滚动的,因此您有一个起点,从那里可以设计页面的其余部分。 (整个页面应该是可滚动的,所以我知道该页面的顶部小部件应该是可滚动的小部件,例如SingleChildScrollView,CustomScrollView,ListView等。)
现在,您的方法没有错,但是您需要知道SizedBox的最终高度,您可以根据列表进行计算。 (太难了)
为解决您的问题,我使用了带有SliverList小部件的CustomScrollView。
return SafeArea(
child: Scaffold(
appBar: AppBar(),
body: CustomScrollView(
slivers: <Widget>[
SliverList(
delegate: SliverChildListDelegate(
[
Padding(
padding: const EdgeInsets.only(left: 25.0, top: 30.0),
child: Text(displayName,
style: TextStyle(
color: Colors.black, fontWeight: FontWeight.bold, fontSize: 20.0)),
),
],
),
),
FutureBuilder(
future: ApiProvider.getPictures(),
builder: ((context, AsyncSnapshot snapshot) {
if (snapshot.hasData) {
if (snapshot.connectionState == ConnectionState.done) {
return SliverList(
delegate: SliverChildBuilderDelegate(
(context, index) => Container(
margin: EdgeInsets.symmetric(vertical: 10),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
displayName,
style: TextStyle(
fontSize: 17, fontWeight: FontWeight.bold),
),
Text(snapshot.data[index].location),
Image(
image: NetworkImage(snapshot.data[index].pictureUrl),
width: MediaQuery.of(context).size.width,
)
],
),
),
childCount: snapshot.data.length));
} else {
return SliverFillRemaining(
child: Center(
child: CircularProgressIndicator(),
),
);
}
} else {
return SliverFillRemaining(
child: Center(
child: CircularProgressIndicator(),
),
);
}
}),
),
],
)));
对于您的问题,还有其他解决方案,但是我认为这是最好的解决方案性能。
如果需要帮助,随时寻求帮助。
答案 1 :(得分:1)
内部ListView
并不是当前工作的正确小部件。您想要做的是在彼此上方显示多个小部件,Column
旨在完成这些小部件。
因此,考虑使用ListView
,而不是使用内部Column
:
Column(
children: snapshot.data.map((data) {
return ListItem(
data: data,
user: _user,
);
}).toList(),
)
请注意,我更新了ListItem
小部件以接受具体的数据部分,而不是列表和索引。
现在,您可能想知道Column
的性能是否比ListView.builder
差,但事实并非如此。这是因为ListView.builder
本身没有滚动,所以它没有懒惰地布局其子级。相反,外部ListView
将决定是否显示所有内部ListView
。
从长远来看,您可能希望懒惰地初始化窗口小部件(尤其是当您的用户拥有数千张图片时)。 a StackOverflow answer此处介绍如何通过BLoC提供多个Future
。