颤振在ListView中使用Listview.builder-使整个页面可滚动

时间:2019-05-05 11:07:28

标签: listview dart flutter

我想建立一个类似instagram的个人资料页面,其中当前用户的所有帖子都列在Feed中。在此之上,应该显示有关用户的一些信息(头像,关注者数量,帖子数量,个人简介等)。 用户应该可以滚动整个页面。此刻,页面只能滚动到ListView.builder中sizeBox窗口小部件的高度。就是这样:

enter image description here

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 ...

最好的问候。

2 个答案:

答案 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