【问题标题】:Flutter expandable tiles inside grid view在网格视图内颤动可扩展瓷砖
【发布时间】:2021-03-04 06:46:04
【问题描述】:

我正在尝试在颤振上实现此功能,但老实说不知道该怎么做。几周以来我一直在努力解决这个问题,我尝试了 flutter_staggered_grid_view,这是最接近这个的,但这也无济于事。有没有人知道如何实现这个效果?

【问题讨论】:

    标签: flutter flutter-layout flutter-gridview


    【解决方案1】:

    您可以将 Wrap 小部件用作网格,并使用带有 AnimatedContainer 的一些自定义小部件来展开和收回块。

    //number of childs used in the example
    static const itemCount = 8;
    
    //list of each bloc expandable state, that is changed to trigger the animation of the AnimatedContainer 
    List<bool> expandableState = List.generate(itemCount, (index) => false);
    
    Widget bloc (double width, int index) {
      bool isExpanded = expandableState[index];
    
      return GestureDetector(
        onTap: () {
          setState(() {
            //changing the current expandableState
            expandableState[index] = !isExpanded;
          });
        },
        child: AnimatedContainer(
          duration: Duration(milliseconds: 200),
          margin: const EdgeInsets.all(20.0),
          width: !isExpanded ? width * 0.4 : width * 0.8,
          height: !isExpanded ? width * 0.4 : width * 0.8,
          color: Colors.red,
        ),
      );
    }
    
    @override
    Widget build(BuildContext context) {
      double width = MediaQuery.of(context).size.width;
    
      return Scaffold(
        body: Align(
          child: SingleChildScrollView(
            child: Wrap(
              children: List.generate(itemCount, (index) {
                return bloc(width, index);
              }),
            ),
          ),
        ),
      );
    }
    

    【讨论】:

      【解决方案2】:

      您可以有一个应该展开的项目列表,并相应地将它们布置在网格视图中(例如使用 flutter_staggered_grid_view)。

      我编辑了写成in the library docs的例子,得到如下结果:

      基本上,

      1. 创建一个StatefulWidget 并向其中添加一个列表 (_expandedIndices)。列表的目的是跟踪展开的项目的索引。

      2. 在网格单元格上添加GestureDetector 以检测点击并从列表中添加/删除索引(如果索引不存在,则将其添加到列表中,否则将其删除)。

      不要忘记将更新列表的代码放在setState中。

      1. staggeredTileBuilder中配置crossAxisCellCountmainAxisCellCount,根据index中的项目是否应该展开。
      class StaggeredGridViewWithExpandableCells extends StatefulWidget {
        @override
        _StaggeredGridViewWithExpandableCellsState createState() =>
            _StaggeredGridViewWithExpandableCellsState();
      }
      
      class _StaggeredGridViewWithExpandableCellsState
          extends State<StaggeredGridViewWithExpandableCells> {
        final _expandedIndices = Set<int>();
      
        @override
        Widget build(BuildContext context) {
          return StaggeredGridView.countBuilder(
            crossAxisCount: 4,
            itemCount: 16,
            itemBuilder: (BuildContext context, int index) => GestureDetector(
              onTap: () => setState(() => _expandedIndices.contains(index) ? _expandedIndices.remove(index) : _expandedIndices.add(index)),
              child: new Container(
                  color: Colors.green,
                  child: new Center(
                    child: new CircleAvatar(
                      backgroundColor: Colors.white,
                      child: new Text('$index'),
                    ),
                  )),
            ),
            staggeredTileBuilder: (int index) =>
                new StaggeredTile.count(_expandedIndices.contains(index) ? 4 : 2, 1),
            mainAxisSpacing: 4.0,
            crossAxisSpacing: 4.0,
          );
        }
      }
      

      【讨论】:

        【解决方案3】:

        您可以使用 Wrap 小部件来实现结果。请看下面的代码。

        import 'package:flutter/material.dart';
        
        final Color darkBlue = const Color.fromARGB(255, 18, 32, 47);
        
        void main() {
          runApp(MyApp());
        }
        
        class MyApp extends StatelessWidget {
          @override
          Widget build(BuildContext context) {
            return MaterialApp(
              theme: ThemeData.dark().copyWith(scaffoldBackgroundColor: darkBlue),
              debugShowCheckedModeBanner: false,
              home: Scaffold(
                appBar: AppBar(title: const Text("Demo")),
                body: Center(
                  child: MyWidget(),
                ),
              ),
            );
          }
        }
        
        class MyWidget extends StatefulWidget {
          @override
          _MyWidgetState createState() => _MyWidgetState();
        }
        
        class _MyWidgetState extends State<MyWidget> {
          final int _cells = 8;
          final double _containerSizeSmall = 75;
          final double _containerSizeLarge = 170;
          final double _padding = 10;
          int _clicked = 0;
          @override
          Widget build(BuildContext context) {
            final Size size = MediaQuery.of(context).size;
            return SingleChildScrollView(
              child: Container(
                height: size.height,
                width: 240,
                child: Wrap(
                  children: List.generate(
                    _cells,
                    (col) => Padding(
                      padding: EdgeInsets.all(_padding),
                      child: GestureDetector(
                        onTap: () {
                          setState(() {
                            _clicked != col + 1 ? _clicked = col + 1 : _clicked = 0;
                          });
                        },
                        child: Container(
                          height: _clicked == col + 1
                              ? _containerSizeLarge
                              : _containerSizeSmall,
                          width: _clicked == col + 1
                              ? _containerSizeLarge
                              : _containerSizeSmall,
                          decoration: const BoxDecoration(
                            color: Colors.blue,
                            borderRadius: const BorderRadius.all(
                              const Radius.circular(5),
                            ),
                          ),
                          child: Center(child: Text('${col + 1}')),
                        ),
                      ),
                    ),
                  ),
                ),
              ),
            );
          }
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2021-04-10
          • 2012-05-28
          • 1970-01-01
          • 1970-01-01
          • 2019-05-10
          • 1970-01-01
          • 1970-01-01
          • 2021-04-01
          相关资源
          最近更新 更多