點燈坊

失くすものさえない今が強くなるチャンスよ

GridView 顯示水平清單 (Builder)

Sam Xiao's Avatar 2024-11-28

GridView 適合顯示水平清單,且自動根據目前寬度換行。

Version

Flutter 3.24.5

Flutter

builder01

  • Android 與 iOS 都成功使用 GridView 實現水平清單

GridView

import 'package:flutter/material.dart';

class Home extends StatefulWidget {
  const Home({super.key});

  
  State<Home> createState() => _Home();
}

class _Home extends State<Home> {
  final List<String> data = List.generate(
    8,
    (index) => 'Item ${index + 1}',
  );

  
  Widget build(BuildContext context) {
    var appBar = AppBar(
      title: const Text(
        'GridView.builder',
      ),
    );

    var gridView = GridView.builder(
      gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
        crossAxisCount: 2,
        crossAxisSpacing: 8,
        mainAxisSpacing: 8,
        childAspectRatio: 2,
      ),
      itemCount: data.length,
      itemBuilder: (
        BuildContext context,
        int index,
      ) {
        return Container(
          alignment: Alignment.center,
          decoration: BoxDecoration(
            color: Colors.blue,
            borderRadius: BorderRadius.circular(8),
          ),
          child: Text(
            data[index],
            style: const TextStyle(
              color: Colors.white,
            ),
          ),
        );
      },
    );

    var body = Padding(
      padding: const EdgeInsets.all(8.0),
      child: gridView,
    );
    
    return Scaffold(
      appBar: appBar,
      body: body,
    );
  }
}

Line 11

final List<String> data = List.generate(
  8,
  (index) => 'Item ${index + 1}',
);
  • List.generate():產生 8 筆 List 假資料

Line 25

var gridView = GridView.builder(
  gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
    crossAxisCount: 2,
    crossAxisSpacing: 8,
    mainAxisSpacing: 8,
    childAspectRatio: 2,
  ),
  itemCount: data.length,
)
  • GridView.builder():建立 GridView
    • gridDelegate:使用 SliverGridDelegateWithFixedCrossAxisCount 指定網格佈局

      • crossAxisCount:設定橫軸顯示個數
      • crossAxisSpacing:設定橫軸間距
      • mainAxisSpacing:設定縱軸間距
      • childAspectRatio:設定項目的長寬比例
    • itemCount: data.length,

Line 32

var gridView = GridView.builder(
  itemBuilder: (
    BuildContext context,
    int index,
  ) {
    return Container(
      alignment: Alignment.center,
      decoration: BoxDecoration(
        color: Colors.blue,
        borderRadius: BorderRadius.circular(8),
      ),
      child: Text(
        data[index],
        style: const TextStyle(
          color: Colors.white,
        ),
      ),
    );
  },
)
  • 在 ItemBuilder 內實現每一筆 GridView 的 UI

Conclusion

  • GridView.count()GridView.build() 的功能大致相同
  • GridView.count() 語法較精簡,適合少量資料
  • GridView.build() 語法稍複雜,適合大量資料,並支援 Lazy Loading