如何在Flutter中实现交错的网格视图?

时间:2018-05-20 13:44:28

标签: flutter

我想在Flutter中实现交错网格视图 - 例如Pinterest交错网格视图(过去通过their own Android Widget实现,现在通过Google StaggeredGridLayoutManager

所以要求是:

  • 项目是通过API获取的 - 所以我需要类似于GridView.builder或ListView.builder的东西,以便我可以实现无限滚动
  • 要在网格视图中显示的每个项目,由以下内容组成:
    • 一张图片 - 比如说一张图片
    • 一些文字/视觉信息,包括:可变长度字符串(可能跨越两行或更多行),图标,其他一些文本(例如金额)

我知道有一个名为flutter_staggered_grid_view的插件,但这是没用的,因为它需要提前知道网格每块瓷砖的精确高度 - 当然这不是我的情况。

4 个答案:

答案 0 :(得分:3)

我已更新flutter_staggered_grid_view包。

现在,您可以添加符合其内容大小的切片:

tile fit content

您必须使用StaggeredTile.fit(this.crossAxisCellCount)构造函数创建切片才能执行此操作。

希望它有所帮助。

答案 1 :(得分:1)

试试这个Flutter Staggered Grid View 0.1.4

demo

希望它有所帮助。

答案 2 :(得分:1)

试试这个。

return new StreamBuilder<QuerySnapshot>(
      stream: Firestore.instance.collection(PRODUCTS_COLLECTION).snapshots(),
      builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
        if (!snapshot.hasData) return new Center(child: new CircularProgressIndicator());
        return new StaggeredGridView.count(
          physics: new BouncingScrollPhysics(),
          crossAxisCount: 2,
          children: buildGrid(snapshot.data.documents), 
          staggeredTiles: generateRandomTiles(snapshot.data.documents.length),
        );
      },
    );

List<Widget> buildGrid(List<DocumentSnapshot> documents) {
  List<Widget> _gridItems = [];
  _products.clear();

  for (DocumentSnapshot document in documents) {
    _products.add(Product.fromDocument(document));
  }

  for (Product product in _products) {
    _gridItems.add(buildGridItem(product));
  }

  return _gridItems;
}

Widget buildGridItem(Product product) {
  return new GestureDetector(
    child: new Card(
      elevation: 2.0,
      margin: const EdgeInsets.all(5.0),
      child: new Stack(
        alignment: Alignment.center,
        children: <Widget>[
          new Hero(
            tag: product.name,
            child: new Image.network(product.imageUrl, fit: BoxFit.cover),
          ),
          new Align(
            child: new Container(
              padding: const EdgeInsets.all(6.0),
              child: new Column(
                mainAxisSize: MainAxisSize.min,
                crossAxisAlignment: CrossAxisAlignment.start,
                children: <Widget>[
                  new Text('\u20B9 ${product.price}',
                      style: new TextStyle(
                          color: Colors.white,
                          fontWeight: FontWeight.bold,
                          fontSize: 16.0)),
                  new Text(product.name,
                      style: new TextStyle(color: Colors.white)),
                ],
              ),
              color: Colors.black.withOpacity(0.4),
              width: double.infinity,
            ),
            alignment: Alignment.bottomCenter,
          ),
        ],
      ),
    ),
    onTap: () async {
      // TODO
    },
  );
}

List<StaggeredTile> generateRandomTiles(int count) {
  Random rnd = new Random();
  List<StaggeredTile> _staggeredTiles = [];
  for (int i=0; i<count; i++) {
    num mainAxisCellCount = 0;
    double temp = rnd.nextDouble();

    if (temp > 0.6) {
      mainAxisCellCount = temp + 0.5;
    } else if (temp < 0.3) {
      mainAxisCellCount = temp + 0.9;
    } else {
      mainAxisCellCount = temp + 0.7;
    }
    _staggeredTiles.add(new StaggeredTile.count(rnd.nextInt(1) + 1, mainAxisCellCount));
  }
  return _staggeredTiles;
}

答案 3 :(得分:0)

正如罗曼·拉斯特勒(Romain Rastler)所说,//Class level declarations: var cbPerifMngr:CBPeripheralManager!, mutaSRVC:CBMutableService!, svcCharac:CBMutableCharacteristic! ......... // CBPeripheralManagerDelegate protocol implementation. func peripheralManagerDidUpdateState(_ peripheral: CBPeripheralManager) { print(#function) if peripheral.state == .poweredOn { mutaSRVC = CBMutableService(type: service_UUID, primary: true) svcCharac = CBMutableCharacteristic(type: svcCharac_UUID, properties: [.read, .notify], value: Data(base64Encoded: "Hello!"),//nil,// permissions: .readable) mutaSRVC.characteristics = [svcCharac] cbPerifMngr?.add(mutaSRVC) cbPerifMngr?.publishL2CAPChannel(withEncryption: false) } } 是一个很好的解决方案,并且他会定期进行更新,下面是一个示例,当我们从互联网上获取内容时,我已经建立了不同的高度网格视图(您可以将其应用于API):

StaggeredGridView