點燈坊

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

GridView 使用 ShrinkView 自行決定高度

Sam Xiao's Avatar 2024-11-30

為了避免 Pixel Overflow,實務上會在 body 使用 SingleChildScrollView,但這會導致 GridView 無法顯示。

Version

Flutter 3.24.5

Flutter

shrinkwrap01

  • Android 與 iOS 都成功使用 ShrinkView 使 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 with shrinkWrap',
      ),
    );

    var gridView = GridView.builder(
      shrinkWrap: true,
      physics: const NeverScrollableScrollPhysics(),
      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 = SingleChildScrollView(
      child: Padding(
        padding: const EdgeInsets.all(8.0),
        child: gridView,
      ),
    );

    return Scaffold(
      appBar: appBar,
      body: body,
    );
  }
}

Line 51

var body = SingleChildScrollView(
  child: Padding(
    padding: const EdgeInsets.all(8.0),
    child: gridView,
  ),
);
  • SingleChildScrollView:外部 沒有 限制高度,當內部高度大於 裝置高度時,會自動產生垂直卷軸

Line 24

var gridView = GridView.builder(
  shrinkWrap: true,
  physics: const NeverScrollableScrollPhysics(),
)
  • shrinkWrap: true:由 GridView 本身內容決定高度
  • physics: const NeverScrollableScrollPhysics()GridView 不顯示卷軸

Conclusion

  • GridView 預設會有卷軸,因此會搭配無限高度,但因為 body 已經使用 SingleChildScrollView 對高度不受限,所以預設 GridView 搭配 SingleChildScrollView 會無法顯示,必須搭配 shrinkWrap: trueGridView 本身內容 產生高度 才能顯示
  • GridView 本身亦有卷軸,但由於在 body 已經使用 SingleChildScrollView 有卷軸,為了避免兩層卷軸,shrinkWrap: true 通常會一起搭配 physics: const NeverScrollableScrollPhysics() 使用