Flutter Gridview或StaggeredGridview可变宽度/要填充列的可变项目数

时间:2019-05-27 04:33:19

标签: flutter flutter-layout

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

enter image description here

但是当尝试使用gridview时,我最终得到的是固定数量的按钮和固定宽度,如下所示:

enter image description here

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

我尝试过像这样的Gridview构建器:

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,
    );

我还编辑了构建器的属性,使其具有SliverGridDelagateWithMaxCrossAxisExtent和其他属性。我知道,如果不将其放置在网格中,则按钮会缩小到最小尺寸,但是当在网格中时,它们会膨胀以填满整个列。

我还尝试了多种方法,将交错视图替换为交错视图,如下所示:

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,
      ),

我已经尝试了StaggeredGridView.countBuilder和StaggeredGridView.extent,但是这两者都比我想象的要远。最终,每个gridview行只有一个按钮(看起来像一个listview)。

我不确定自己在做什么错,或者不确定这些小部件是否可行。

感谢您的帮助

2 个答案:

答案 0 :(得分:0)

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

答案 1 :(得分:0)

您必须使用 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: () {},
                    );
                  },
                ),
              ),