如何使用网格 Flutter 同时滚动小部件

Posted

技术标签:

【中文标题】如何使用网格 Flutter 同时滚动小部件【英文标题】:How to scroll widget in same time with grid Flutter 【发布时间】:2021-03-22 00:27:12 【问题描述】:

如何同时滚动小部件

颤动

截图

Image

这是此屏幕的代码

return Scaffold(
    appBar: CustomAppBar(
      scaffoldKey: widget.scaffoldKey,
      // icon: AppIcon.settings,
      // onActionPressed: onSettingIconPressed,
      onSearchChanged: (text) 
        setState(() 
          if (text.length > 0) 
            searching = true;
           else 
            searching = false;
          
        );

        state.filterByUsername(text);
      ,
    ),
    backgroundColor: Colors.white,
    body: new RefreshIndicator(
        backgroundColor: Colors.white,
        onRefresh: () async 
          HapticFeedback.selectionClick();
          setState(() 
            list3 = state2.getPostList(authstate.userModel);
            list3.shuffle();
            onlyImages.shuffle();
          );
          state.getDataFromDatabase();
          return Future.value(true);
        ,

        // mesto povise greed, i ispod search boxa

        child: new Column(
          children: <Widget>[
            searching
                ? ListView.separated(
                    addAutomaticKeepAlives: false,
                    physics: BouncingScrollPhysics(),
                    itemBuilder: (context, index) =>
                        _UserTile(user: list[index]),
                    separatorBuilder: (_, index) => Divider(
                      color: Colors.orange,
                      height: 0,
                    ),
                    itemCount: list?.length ?? 0,
                  )
                : slider(),
            searching
                ? ListView.separated(
                    addAutomaticKeepAlives: false,
                    physics: BouncingScrollPhysics(),
                    itemBuilder: (context, index) =>
                        _UserTile(user: list[index]),
                    separatorBuilder: (_, index) => Divider(
                      color: Colors.orange,
                      height: 0,
                    ),
                    itemCount: list?.length ?? 0,
                  )
                : Container(
                    height: 32,
                    margin: EdgeInsets.only(top: 5, bottom: 5),
                    child: ListView(
                        scrollDirection: Axis.horizontal,
                        children: <Widget>[
                          _tagItem(Icon(Icons.dehaze, color: Colors.orange),
                              'DAJGI', null, Colors.black, () 
                            Navigator.pushNamed(
                                context, '/PhoneConfirmCode');
                          ),
                          _tagItem(null, 'Nature', null,
                              Colors.greenAccent.withOpacity(0.3), null),
                          _tagItem(
                              null, 'Animal', null, Colors.brown, null),
                          _tagItem(null, 'Travel', null, Colors.teal, null),
                          _tagItem(
                              null, 'Happy', null, Colors.orange, null),
                          _tagItem(null, 'Art', null, Colors.blue, null),
                          _tagItem(
                              null, 'Night', null, Colors.blueGrey, null),
                        ]),
                  ),

            // Grid List
            _listOfPosts(),

            // Expanded(
            //   child: GridView.count(
            //     crossAxisCount: 3,
            //     children: List.generate(onlyImages.length, (index) 
            //       return GestureDetector(
            //           onTap: () 
            //             FeedModel model = onlyImages[index];
            //             onPostPressed(context, model);
            //           ,
            //           // onLongPress: () 
            //           //   _createPopupContext;
            //           //   FeedModel model = onlyImages[index];
            //           //   onPostPressed(context, model);
            //           // ,
            //           child: Container(
            //             child: Card(
            //                 child: onlyImages
            //                             .elementAt(index)
            //                             .imagesPath
            //                             .length >
            //                         0
            //                     ? CachedNetworkImage(
            //                         imageUrl: onlyImages
            //                             .elementAt(index)
            //                             .imagesPath[0],
            //                         fit: BoxFit.cover,
            //                       )
            //                     :
            //                     // Container()
            //                     Center(
            //                         child: Text(onlyImages
            //                             .elementAt(index)
            //                             .description),
            //                       )),
            //           ));
            //     
            //     ),
            //   ),
            // ),
          ],
        )));

当我现在开始滚动时,只有网格滚动但小部件不移动,我希望当用户开始滚动时这个小部件会上升。谁能告诉我问题出在哪里以及如何解决?

根据 cmets 中的要求更新了完整代码。

【问题讨论】:

【参考方案1】:

首先,Column 是不可滚动的,所以要使小部件可滚动,就是用ListView 而不是Column 包装这些小部件。所以你可以做这样的事情来使小部件可滚动:

RefreshIndicator(
    backgroundColor: Colors.white,
    onRefresh: (_),
    child: new ListView(
      children: <Widget>[
        // widget 1,
        // widget 2,
        // widget 3,
      ],
),

如果ListView 使小部件可滚动,当ListView 包裹在另一个ListView 中时会发生什么?可滚动内的可滚动? (嗯,有些情况下你想这样做,但这里不是这样,所以是的)。会有错误。

所以为了避免错误,只需添加 shrinkWrap: truephysics: ClampingScrollPhysics() 就可以了,如下所示:

RefreshIndicator(
  backgroundColor: Colors.white,
  onRefresh: (_),
  child: new ListView(
    children: <Widget>[
      // listview
      ListView.separated(
        shrinkWrap: true,                 // <--- add this
        physics: ClampingScrollPhysics(), // <--- and this
        ...
      ),
      // gridview
      GridView.builder(
        shrinkWrap: true,                 // <--- add this
        physics: ClampingScrollPhysics(), // <--- and this
        ...
      ),
    ],
  ),
),

【讨论】:

以上是关于如何使用网格 Flutter 同时滚动小部件的主要内容,如果未能解决你的问题,请参考以下文章

当文本在 Flutter 中溢出时如何使 Text 小部件像选取框一样

Flutter - 如何使列屏幕可滚动

Flutter:使用 Sliver 小部件时如何在滚动时隐藏 BottomAppBar?

Flutter Web 中如何使列可滚动?

如何在 Flutter 中同时滚动多个文本字段

如何将垂直滚动 TextView 添加到 Android 小部件