代码之家  ›  专栏  ›  技术社区  ›  Nicholas Muir

Flatter Gridview或StaggedGridView可变宽度/可变数量的项目填充栏

  •  0
  • Nicholas Muir  · 技术社区  · 7 年前

    我正在尝试显示一个gridview,它有可变的数字和宽度按钮,如下所示:

    enter image description here

    但我在尝试gridview时得到的结果是固定数量的按钮和固定宽度,如下所示:

    enter image description here

    起初,我认为这是默认情况下按钮填充过多的问题,但这不是问题所在,我能够解决这个问题,但网格仍然存在同样的问题。

    我尝试过Gridview builder,如下所示:

    GridView.builder(
          shrinkWrap: true,
          physics: NeverScrollableScrollPhysics(),
          gridDelegate:
          SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 3, childAspectRatio: 3.5, mainAxisSpacing: 4, crossAxisSpacing: 4),
          itemBuilder: (BuildContext context, int index) {
            return InkWell(
              onTap: () {
                //Navigator.of(context).pushNamed(HomePageResultsScreen.id);
              },
              child: ButtonTheme(
                minWidth: 16,
                height: 30,
                child: RaisedButton(
                  padding: EdgeInsets.all(8.0),
                  materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
                  color: Colors.white,
                  child:
                  Center(
                    child: Row(
                      mainAxisSize: MainAxisSize.min,
                      children: <Widget>[
                        CachedNetworkImage(fit: BoxFit.contain,
                          height: 40,
                          width: 40,
                          placeholder: (context, url) => new CircularProgressIndicator(),
                          imageUrl: snapshot.data.documents[index]['icon'].toString(),
                        ),
                        Text(snapshot.data.documents[index]['name'].toString(), textAlign: TextAlign.right, style: TextStyle(fontSize:  10, color: Colors.black,),),
    
                      ],
                    ),
                  ),
                  onPressed: (){
    
                  },
                ),
              ),
    
            );
          },
          itemCount: snapshot.data.documents.length,
        );
    

    我还对构建器的属性进行了编辑,使其具有MaxCrossAxisExtent和其他属性。我知道按钮如果不放在网格内,会缩小到最小尺寸,但当在网格中时,它们会扩展到填充整个列。

    我还尝试了多种方法,用交错的gridview替换gridview,如下所示:

    StaggeredGridView.countBuilder(
            shrinkWrap: true,
            physics: NeverScrollableScrollPhysics(),
            crossAxisCount: 3,
            staggeredTileBuilder: (int index) =>
            new StaggeredTile.count(2, index.isEven ? 2 : 1),
            itemBuilder: (BuildContext context, int index) {
              return InkWell(
                onTap: () {
                  //Navigator.of(context).pushNamed(HomePageResultsScreen.id);
                },
                child: ButtonTheme(
                  minWidth: 16,
                  height: 30,
                  child: RaisedButton(
                    padding: EdgeInsets.all(8.0),
                    materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
                    color: Colors.white,
                    child:
                    Row(
                      mainAxisSize: MainAxisSize.min,
                      children: <Widget>[
                        CachedNetworkImage(fit: BoxFit.contain,
                          height: 20,
                          width: 20,
                          placeholder: (context, url) => new CircularProgressIndicator(),
                          imageUrl: snapshot.data.documents[index]['icon'].toString(),
                        ),
                        Text(snapshot.data.documents[index]['name'].toString(), textAlign: TextAlign.center, style: TextStyle(fontSize:  10, color: Colors.black,),),
    
                      ],
                    ),
                    onPressed: (){
    
                    },
                  ),
                ),
    
              );
            },
            itemCount: snapshot.data.documents.length,
          ),
    

    我试过这两种观点。countBuilder和EdgridView。但这两个都比我想象的要远。每个gridview行(看起来像一个listview)只有一个按钮。

    我不确定我做错了什么,也不确定这些小部件是否可能做到这一点。

    谢谢你的帮助

    0 回复  |  直到 7 年前
        1
  •  1
  •   BIS Tech    5 年前

    你必须使用 StaggeredGridView 您必须找到逻辑来计算项目宽度和设置 StaggeredTile.count .

      final List<String> testing = ['Baby Foods', 'Confectionery', 'Coffee', 'Packets & Units','Packets & Units unis', 'Processed Cheese', 'Factional Care', 'Sauce', 'Sauc'];
    
        Container(
                    width: width,
                    child: StaggeredGridView.countBuilder(
                      itemCount: resting.length,
                      physics: NeverScrollableScrollPhysics(),
                      shrinkWrap: true,
                      crossAxisCount: 8,
                      staggeredTileBuilder: (int index) {
                        if (testing[index].length < 5) {
                          return StaggeredTile.count(2, 1);
                        } else if (testing[index].length < 16) {
                          return StaggeredTile.count(3, 1);
                        } else {
                          return StaggeredTile.count(4, 1);
                        }
                      },
                      mainAxisSpacing: 12.0,
                      crossAxisSpacing: 10.0,
                      itemBuilder: (BuildContext context, int index) {
                        return TextButton(
                          child: Text(testing[index]),
                          onPressed: () {},
                        );
                      },
                    ),
                  ),
    
        2
  •  0
  •   anupam das    6 年前
    # # Staggered View
    # ScreenShot
    ![alt text](https://github.com/Anup2712/flutterAnup/blob/master/StaggeredView/Screenshot.jpg)
    
    # What is it?
    A Flutter staggered grid view which supports multiple columns with rows of varying sizes.
    It’s a grid layout where the cross axis is divided in multiple equally sized parts, and places elements in optimal position based on available main axis space.
    You’ve probably came across some app or website design with staggered grid layout like Pinterest:
    
    # For understand the code
    
    To help you to understand the code, you can see that this grid of 10 tiles is divided into 4 columns:
    
    ![alt text](https://github.com/Anup2712/flutterAnup/blob/master/StaggeredView/understanding.png)
    
    
    # Let's Get Started
    <H3>1 - Depend on it</h3>
    <h6><b>Add it to your package's pubspec.yaml file</b></h6>
    <pre>dependencies:
      fl_chart: ^0.6.1</pre>
    <H3>2 - Install it</h3>
    <h6><b>Install packages from the command line</b></h6>
    <pre>flutter packages get</pre>
    <H3>2 - Getting Started</h3>
    <h6><b>Import the package:</b></h6>
    <pre>import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart';</pre>
    
    <pre>import 'package:flutter/material.dart';
    import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart';
    import 'package:ofsdp/pages/home.dart';
    import 'package:ofsdp/util/appdrawer.dart';
    
    class AdministrativeUvit extends StatefulWidget {
      @override
      _AdministrativeUvitState createState() => _AdministrativeUvitState();
    }
    
    class _AdministrativeUvitState extends State<AdministrativeUvit> {
      var _scaffoldkey = GlobalKey<ScaffoldState>();
      List<StaggeredTile> _staggeredTiles = const <StaggeredTile>[
        const StaggeredTile.count(1, 1),
        const StaggeredTile.count(1, 1),
        const StaggeredTile.count(1, 1),
        const StaggeredTile.count(1, 1),
        const StaggeredTile.count(1, 1.5),
        const StaggeredTile.count(1, 1.5),
      ];
    
      List<Widget> _tiles = const <Widget>[
      const _Example01Tile(Colors.green, Icons.widgets),
      const _Example01Tile(Colors.lightBlue, Icons.wifi),
      const _Example01Tile(Colors.amber, Icons.panorama_wide_angle),
      const _Example01Tile(Colors.brown, Icons.map),
      const _Example01Tile(Colors.deepOrange, Icons.send),
      const _Example01Tile(Colors.indigo, Icons.airline_seat_flat),
      const _Example01Tile(Colors.red, Icons.bluetooth),
      const _Example01Tile(Colors.pink, Icons.battery_alert),
      const _Example01Tile(Colors.purple, Icons.desktop_windows),
      const _Example01Tile(Colors.blue, Icons.radio),
    ];
      @override
      Widget build(BuildContext context) {
        return Stack(
          children: <Widget>[
            Image.asset(
              "assets/images/footer.jpg",
              height: MediaQuery.of(context).size.height,
              width: MediaQuery.of(context).size.width,
              fit: BoxFit.cover,
            ),
            Scaffold(
                backgroundColor: Colors.transparent,
                appBar: AppBar(
                  backgroundColor: Color.fromRGBO(117, 80, 0, 1),
                  title: const Text("ADMINISTRATIVE UNIT"),
                  actions: <Widget>[
                    IconButton(
                      icon: Icon(Icons.home),
                      onPressed: () {
                        Navigator.of(context).pushReplacement(
                          MaterialPageRoute(
                            builder: (context) => HomePage(),
                          ),
                        );
                      },
                    )
                  ],
                ),
                drawer: AppDrawer(),
                key: _scaffoldkey,
    
                body: new Padding(
                    padding: const EdgeInsets.only(top: 12.0),
                    child: new StaggeredGridView.count(
                      crossAxisCount: 2,
                      staggeredTiles: _staggeredTiles,
                      children: _tiles,
                      mainAxisSpacing: 4.0,
                      crossAxisSpacing: 4.0,
                      padding: const EdgeInsets.all(4.0),
                    )))
          ],
        );
      }
    }
    class _Example01Tile extends StatelessWidget {
      const _Example01Tile(this.backgroundColor, this.iconData);
    
      final Color backgroundColor;
      final IconData iconData;
    
      @override
      Widget build(BuildContext context) {
        return new Card(
          color: backgroundColor,
          child: new InkWell(
            onTap: () {},
            child: new Center(
              child: new Padding(
                padding: const EdgeInsets.all(4.0),
                child: new Icon(
                  iconData,
                  color: Colors.white,
                ),
              ),
            ),
          ),
        );
      }
    }</pre>
    
        3
  •  0
  •   Abdullah Zakhoi    4 年前

    如果这些容器不是按钮(意味着你不需要点击每个按钮来做特定的事情),那么你可以使用 Wrap Widget

    https://www.youtube.com/watch?v=z5iw2SeFx2M

    https://medium.com/flutter-community/flutter-wrap-widget-e1ee0b005b16

    推荐文章